From cb143c44c32f878b36e07c49f07e8521aa26269a Mon Sep 17 00:00:00 2001 From: Tim Hughes Date: Sat, 27 Sep 2014 13:20:19 +0100 Subject: [PATCH 001/277] Fixed size_t to bool warning and internal compiler error with MSVC. --- eth/main.cpp | 8 +++++++- libwebthree/WebThree.h | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/eth/main.cpp b/eth/main.cpp index a9ea43f14..03be8b969 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -300,7 +300,13 @@ int main(int argc, char** argv) cout << credits(); NetworkPreferences netPrefs(listenPort, publicIP, upnp, useLocal); - dev::WebThreeDirect web3("Ethereum(++)/" + clientName + "v" + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), dbPath, false, mode == NodeMode::Full ? set{"eth", "shh"} : set{}, netPrefs); + dev::WebThreeDirect web3( + "Ethereum(++)/" + clientName + "v" + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), + dbPath, + false, + mode == NodeMode::Full ? set{"eth", "shh"} : set(), + netPrefs + ); web3.setIdealPeerCount(peers); eth::Client* c = mode == NodeMode::Full ? web3.ethereum() : nullptr; diff --git a/libwebthree/WebThree.h b/libwebthree/WebThree.h index 06717ee26..cae6fd6f8 100644 --- a/libwebthree/WebThree.h +++ b/libwebthree/WebThree.h @@ -93,7 +93,7 @@ public: void connect(std::string const& _seedHost, unsigned short _port = 30303); /// Is the network subsystem up? - bool haveNetwork() { return peerCount(); } + bool haveNetwork() { return peerCount() != 0; } /// Save peers dev::bytes savePeers(); From a23fea0917459494322c3077f4ff8a46cb53a67b Mon Sep 17 00:00:00 2001 From: Tim Hughes Date: Sat, 27 Sep 2014 13:23:02 +0100 Subject: [PATCH 002/277] Suppress warnings from boost mpl during moc compile. --- alethzero/MainWin.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index ce1a9b670..7aee0c376 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -21,6 +21,9 @@ #pragma once +#ifdef Q_MOC_RUN +#define BOOST_MPL_IF_HPP_INCLUDED +#endif #include #include From 6857416c09d783519798cb034048232be544df01 Mon Sep 17 00:00:00 2001 From: Tim Hughes Date: Sat, 27 Sep 2014 13:23:19 +0100 Subject: [PATCH 003/277] Update MSVC projects. --- libdevcore/_libdevcore.cpp | 2 ++ windows/Alethzero.vcxproj | 3 ++- windows/Alethzero.vcxproj.filters | 2 ++ windows/LibEthereum.vcxproj | 30 ++++++++++++++++++++++++++++- windows/LibEthereum.vcxproj.filters | 27 ++++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 2 deletions(-) diff --git a/libdevcore/_libdevcore.cpp b/libdevcore/_libdevcore.cpp index 4160a7602..1b34a5911 100644 --- a/libdevcore/_libdevcore.cpp +++ b/libdevcore/_libdevcore.cpp @@ -6,5 +6,7 @@ #include "FixedHash.cpp" #include "Guards.cpp" #include "Log.cpp" +#include "RangeMask.cpp" #include "RLP.cpp" +#include "Worker.cpp" #endif diff --git a/windows/Alethzero.vcxproj b/windows/Alethzero.vcxproj index d418e5d03..38dbd6265 100644 --- a/windows/Alethzero.vcxproj +++ b/windows/Alethzero.vcxproj @@ -176,6 +176,7 @@ + @@ -307,4 +308,4 @@ - + \ No newline at end of file diff --git a/windows/Alethzero.vcxproj.filters b/windows/Alethzero.vcxproj.filters index e8f008522..ef47bdba0 100644 --- a/windows/Alethzero.vcxproj.filters +++ b/windows/Alethzero.vcxproj.filters @@ -11,6 +11,7 @@ + @@ -31,5 +32,6 @@ Windows + \ No newline at end of file diff --git a/windows/LibEthereum.vcxproj b/windows/LibEthereum.vcxproj index 134171843..db1362363 100644 --- a/windows/LibEthereum.vcxproj +++ b/windows/LibEthereum.vcxproj @@ -49,12 +49,24 @@ true true + + true + true + true + true + true true true true + + true + true + true + true + @@ -90,6 +102,7 @@ + @@ -159,6 +172,7 @@ true + true true @@ -223,6 +237,12 @@ true true + + true + true + true + true + true true @@ -235,6 +255,12 @@ true true + + true + true + true + true + @@ -289,6 +315,7 @@ + @@ -376,6 +403,7 @@ true true + true true @@ -527,4 +555,4 @@ - + \ No newline at end of file diff --git a/windows/LibEthereum.vcxproj.filters b/windows/LibEthereum.vcxproj.filters index b6e2dc070..848b8308d 100644 --- a/windows/LibEthereum.vcxproj.filters +++ b/windows/LibEthereum.vcxproj.filters @@ -178,6 +178,18 @@ libethereum + + libdevcore + + + libdevcore + + + libethereum + + + libwebthree + @@ -390,6 +402,18 @@ libethereum + + libdevcore + + + libdevcore + + + libethereum + + + libwebthree + @@ -422,5 +446,8 @@ {36748e80-c977-4fee-84e6-699c039dff87} + + {d838fece-fc20-42f6-bff5-97c236159b80} + \ No newline at end of file From 01af0e88cd1c0d42d5639b78467a5e4f7b967d85 Mon Sep 17 00:00:00 2001 From: caktux Date: Sun, 12 Oct 2014 02:14:21 -0400 Subject: [PATCH 004/277] build status --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 7529fed50..d1568402c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ ## Ethereum C++ Client. +[![Build +Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20C%2B%2B%20master%20branch)](http://build.ethdev.com/builders/Linux%20C%2B%2B%20master%20branch/builds/-1) master [![Build +Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20C%2B%2B%20develop%20branch)](http://build.ethdev.com/builders/Linux%20C%2B%2B%20develop%20branch/builds/-1) develop + By Gav Wood, 2014. Based on a design by Vitalik Buterin. From 3d70090fe43bb1693129bd7d6ca03ccfea059091 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Mon, 3 Nov 2014 16:54:03 +0100 Subject: [PATCH 005/277] jsonrpc 0.3.0 working, needs cleanup --- cmake/EthDependenciesDeprecated.cmake | 38 +- eth/main.cpp | 2 +- libqethereum/QEthereum.h | 3 +- libweb3jsonrpc/CMakeLists.txt | 2 + libweb3jsonrpc/CorsHttpServer.h | 3 +- libweb3jsonrpc/WebThreeStubServer.cpp | 2 +- libweb3jsonrpc/WebThreeStubServer.h | 3 +- libweb3jsonrpc/abstractwebthreestubserver.h | 368 +++++----- libweb3jsonrpc/spec.json | 100 +-- neth/main.cpp | 2 +- test/CMakeLists.txt | 1 + test/jsonrpc.cpp | 11 +- test/webthreestubclient.h | 713 ++++++++------------ 13 files changed, 560 insertions(+), 688 deletions(-) diff --git a/cmake/EthDependenciesDeprecated.cmake b/cmake/EthDependenciesDeprecated.cmake index d1c51f6c4..d815bef3e 100644 --- a/cmake/EthDependenciesDeprecated.cmake +++ b/cmake/EthDependenciesDeprecated.cmake @@ -125,21 +125,47 @@ else() message(STATUS "Failed to find the miniupnpc headers!") endif () - find_path( JSONRPC_ID jsonrpc/rpc.h - /usr/include - /usr/local/include - ) + find_path( JSONRPC_ID jsonrpccpp/server.h + /usr/include + /usr/local/include + ) + if ( JSONRPC_ID ) message(STATUS "Found jsonrpc headers") - find_library( JSONRPC_LS NAMES jsonrpc + find_library( JSONRPC_LS NAMES jsonrpccpp-server PATHS /usr/lib /usr/local/lib /opt/local/lib /usr/lib/*/ ) - if ( JSONRPC_LS ) + + find_library( JSONRPC_COMMON_LS NAMES jsonrpccpp-common + PATHS + /usr/lib + /usr/local/lib + /opt/local/lib + /usr/lib/*/ + ) + + find_library( JSONCPP_LS NAMES jsoncpp + /usr/lib + /usr/local/lib + /opt/local/lib + /usr/lib/*/ + ) + + find_library( JSONRPC_CLIENT_LS NAMES jsonrpccpp-client + PATHS + /usr/lib/ + /usr/local/lib + /opt/local/lib + /usr/lib/*/ + ) + + if ( JSONRPC_LS AND JSONRPC_COMMON_LS ) message(STATUS "Found jsonrpc library: ${JSONRPC_LS}") + message(STATUS "Found jsonrpc-common library: ${JSONRPC_COMMON_LS}") add_definitions(-DETH_JSONRPC) else () message(STATUS "Failed to find the jsonrpc library!") diff --git a/eth/main.cpp b/eth/main.cpp index 759dd40d0..447729c1a 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -28,7 +28,7 @@ #include #include #if ETH_JSONRPC -#include +//#include #include #endif #include diff --git a/libqethereum/QEthereum.h b/libqethereum/QEthereum.h index 4f276b7e1..b4c17fdab 100644 --- a/libqethereum/QEthereum.h +++ b/libqethereum/QEthereum.h @@ -25,7 +25,8 @@ #include #include -#include +#include +//#include class QWebThree: public QObject { diff --git a/libweb3jsonrpc/CMakeLists.txt b/libweb3jsonrpc/CMakeLists.txt index b24a11196..6966cd10a 100644 --- a/libweb3jsonrpc/CMakeLists.txt +++ b/libweb3jsonrpc/CMakeLists.txt @@ -23,7 +23,9 @@ if(MINIUPNPC_LS) endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) +target_link_libraries(${EXECUTABLE} ${JSONCPP_LS}) target_link_libraries(${EXECUTABLE} ${JSONRPC_LS}) +target_link_libraries(${EXECUTABLE} ${JSONRPC_COMMON_LS}) target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) if(READLINE_LS) target_link_libraries(${EXECUTABLE} ${READLINE_LS}) diff --git a/libweb3jsonrpc/CorsHttpServer.h b/libweb3jsonrpc/CorsHttpServer.h index d3bd8a6e9..5dd3130a4 100644 --- a/libweb3jsonrpc/CorsHttpServer.h +++ b/libweb3jsonrpc/CorsHttpServer.h @@ -19,7 +19,8 @@ * @date 2014 */ -#include +#include +//#include namespace jsonrpc { diff --git a/libweb3jsonrpc/WebThreeStubServer.cpp b/libweb3jsonrpc/WebThreeStubServer.cpp index e7eb62e04..ed5907f53 100644 --- a/libweb3jsonrpc/WebThreeStubServer.cpp +++ b/libweb3jsonrpc/WebThreeStubServer.cpp @@ -217,7 +217,7 @@ static Json::Value toJson(h256 const& _h, shh::Envelope const& _e, shh::Message WebThreeStubServer::WebThreeStubServer(jsonrpc::AbstractServerConnector* _conn, WebThreeDirect& _web3, std::vector const& _accounts): - AbstractWebThreeStubServer(_conn), + AbstractWebThreeStubServer(*_conn), m_web3(_web3) { setAccounts(_accounts); diff --git a/libweb3jsonrpc/WebThreeStubServer.h b/libweb3jsonrpc/WebThreeStubServer.h index b18faf95a..193f1f6ff 100644 --- a/libweb3jsonrpc/WebThreeStubServer.h +++ b/libweb3jsonrpc/WebThreeStubServer.h @@ -29,7 +29,8 @@ #pragma warning(pop) #include -#include +//#include +#include #include #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" diff --git a/libweb3jsonrpc/abstractwebthreestubserver.h b/libweb3jsonrpc/abstractwebthreestubserver.h index ac6893933..90ee422a0 100644 --- a/libweb3jsonrpc/abstractwebthreestubserver.h +++ b/libweb3jsonrpc/abstractwebthreestubserver.h @@ -1,323 +1,287 @@ /** - * THIS FILE IS GENERATED BY jsonrpcstub, DO NOT CHANGE IT!!!!! + * This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY! */ -#ifndef _ABSTRACTWEBTHREESTUBSERVER_H_ -#define _ABSTRACTWEBTHREESTUBSERVER_H_ +#ifndef JSONRPC_CPP_STUB_ABSTRACTWEBTHREESTUBSERVER_H_ +#define JSONRPC_CPP_STUB_ABSTRACTWEBTHREESTUBSERVER_H_ -#include +#include class AbstractWebThreeStubServer : public jsonrpc::AbstractServer { public: - AbstractWebThreeStubServer(jsonrpc::AbstractServerConnector* conn) : - jsonrpc::AbstractServer(conn) + AbstractWebThreeStubServer(jsonrpc::AbstractServerConnector &conn) : jsonrpc::AbstractServer(conn) { - this->bindAndAddMethod(new jsonrpc::Procedure("account", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::accountI); - this->bindAndAddMethod(new jsonrpc::Procedure("accounts", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, NULL), &AbstractWebThreeStubServer::accountsI); - this->bindAndAddMethod(new jsonrpc::Procedure("addToGroup", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::addToGroupI); - this->bindAndAddMethod(new jsonrpc::Procedure("balanceAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::balanceAtI); - this->bindAndAddMethod(new jsonrpc::Procedure("blockByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::blockByHashI); - this->bindAndAddMethod(new jsonrpc::Procedure("blockByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::blockByNumberI); - this->bindAndAddMethod(new jsonrpc::Procedure("call", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::callI); - this->bindAndAddMethod(new jsonrpc::Procedure("changed", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::changedI); - this->bindAndAddMethod(new jsonrpc::Procedure("codeAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::codeAtI); this->bindAndAddMethod(new jsonrpc::Procedure("coinbase", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::coinbaseI); - this->bindAndAddMethod(new jsonrpc::Procedure("compile", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::compileI); - this->bindAndAddMethod(new jsonrpc::Procedure("countAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_REAL, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::countAtI); - this->bindAndAddMethod(new jsonrpc::Procedure("defaultBlock", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::defaultBlockI); - this->bindAndAddMethod(new jsonrpc::Procedure("gasPrice", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::gasPriceI); - this->bindAndAddMethod(new jsonrpc::Procedure("get", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::getI); - this->bindAndAddMethod(new jsonrpc::Procedure("getMessages", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::getMessagesI); - this->bindAndAddMethod(new jsonrpc::Procedure("getString", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::getStringI); - this->bindAndAddMethod(new jsonrpc::Procedure("haveIdentity", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::haveIdentityI); + this->bindAndAddMethod(new jsonrpc::Procedure("setCoinbase", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::setCoinbaseI); this->bindAndAddMethod(new jsonrpc::Procedure("listening", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::listeningI); + this->bindAndAddMethod(new jsonrpc::Procedure("setListening", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::setListeningI); this->bindAndAddMethod(new jsonrpc::Procedure("mining", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::miningI); - this->bindAndAddMethod(new jsonrpc::Procedure("newFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::newFilterI); - this->bindAndAddMethod(new jsonrpc::Procedure("newFilterString", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::newFilterStringI); - this->bindAndAddMethod(new jsonrpc::Procedure("newGroup", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::newGroupI); - this->bindAndAddMethod(new jsonrpc::Procedure("newIdentity", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::newIdentityI); - this->bindAndAddMethod(new jsonrpc::Procedure("number", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::numberI); + this->bindAndAddMethod(new jsonrpc::Procedure("setMining", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::setMiningI); + this->bindAndAddMethod(new jsonrpc::Procedure("gasPrice", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::gasPriceI); + this->bindAndAddMethod(new jsonrpc::Procedure("account", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::accountI); + this->bindAndAddMethod(new jsonrpc::Procedure("accounts", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, NULL), &AbstractWebThreeStubServer::accountsI); this->bindAndAddMethod(new jsonrpc::Procedure("peerCount", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::peerCountI); - this->bindAndAddMethod(new jsonrpc::Procedure("post", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::postI); - this->bindAndAddMethod(new jsonrpc::Procedure("put", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::putI); - this->bindAndAddMethod(new jsonrpc::Procedure("putString", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::putStringI); - this->bindAndAddMethod(new jsonrpc::Procedure("setCoinbase", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::setCoinbaseI); + this->bindAndAddMethod(new jsonrpc::Procedure("defaultBlock", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::defaultBlockI); this->bindAndAddMethod(new jsonrpc::Procedure("setDefaultBlock", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::setDefaultBlockI); - this->bindAndAddMethod(new jsonrpc::Procedure("setListening", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::setListeningI); - this->bindAndAddMethod(new jsonrpc::Procedure("setMining", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::setMiningI); - this->bindAndAddMethod(new jsonrpc::Procedure("shhChanged", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::shhChangedI); - this->bindAndAddMethod(new jsonrpc::Procedure("shhNewFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::shhNewFilterI); - this->bindAndAddMethod(new jsonrpc::Procedure("shhUninstallFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::shhUninstallFilterI); + this->bindAndAddMethod(new jsonrpc::Procedure("number", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::numberI); + this->bindAndAddMethod(new jsonrpc::Procedure("balanceAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::balanceAtI); this->bindAndAddMethod(new jsonrpc::Procedure("stateAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::stateAtI); + this->bindAndAddMethod(new jsonrpc::Procedure("countAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_REAL, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::countAtI); + this->bindAndAddMethod(new jsonrpc::Procedure("codeAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::codeAtI); this->bindAndAddMethod(new jsonrpc::Procedure("transact", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::transactI); + this->bindAndAddMethod(new jsonrpc::Procedure("call", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::callI); + this->bindAndAddMethod(new jsonrpc::Procedure("blockByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::blockByHashI); + this->bindAndAddMethod(new jsonrpc::Procedure("blockByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::blockByNumberI); this->bindAndAddMethod(new jsonrpc::Procedure("transactionByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::transactionByHashI); this->bindAndAddMethod(new jsonrpc::Procedure("transactionByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_INTEGER,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::transactionByNumberI); this->bindAndAddMethod(new jsonrpc::Procedure("uncleByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::uncleByHashI); this->bindAndAddMethod(new jsonrpc::Procedure("uncleByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_INTEGER,"param2",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::uncleByNumberI); + this->bindAndAddMethod(new jsonrpc::Procedure("compile", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::compileI); + this->bindAndAddMethod(new jsonrpc::Procedure("newFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::newFilterI); + this->bindAndAddMethod(new jsonrpc::Procedure("newFilterString", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::newFilterStringI); this->bindAndAddMethod(new jsonrpc::Procedure("uninstallFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::uninstallFilterI); - + this->bindAndAddMethod(new jsonrpc::Procedure("changed", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::changedI); + this->bindAndAddMethod(new jsonrpc::Procedure("getMessages", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::getMessagesI); + this->bindAndAddMethod(new jsonrpc::Procedure("put", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::putI); + this->bindAndAddMethod(new jsonrpc::Procedure("get", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::getI); + this->bindAndAddMethod(new jsonrpc::Procedure("putString", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::putStringI); + this->bindAndAddMethod(new jsonrpc::Procedure("getString", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::getStringI); + this->bindAndAddMethod(new jsonrpc::Procedure("post", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::postI); + this->bindAndAddMethod(new jsonrpc::Procedure("newIdentity", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::newIdentityI); + this->bindAndAddMethod(new jsonrpc::Procedure("haveIdentity", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::haveIdentityI); + this->bindAndAddMethod(new jsonrpc::Procedure("newGroup", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::newGroupI); + this->bindAndAddMethod(new jsonrpc::Procedure("addToGroup", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::addToGroupI); + this->bindAndAddMethod(new jsonrpc::Procedure("shhNewFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::shhNewFilterI); + this->bindAndAddMethod(new jsonrpc::Procedure("shhUninstallFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::shhUninstallFilterI); + this->bindAndAddMethod(new jsonrpc::Procedure("shhChanged", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::shhChangedI); } - - inline virtual void accountI(const Json::Value& request, Json::Value& response) + + inline virtual void coinbaseI(const Json::Value &request, Json::Value &response) { - response = this->account(); + (void)request; + response = this->coinbase(); } - - inline virtual void accountsI(const Json::Value& request, Json::Value& response) + inline virtual void setCoinbaseI(const Json::Value &request, Json::Value &response) { - response = this->accounts(); + response = this->setCoinbase(request[0u].asString()); } - - inline virtual void addToGroupI(const Json::Value& request, Json::Value& response) + inline virtual void listeningI(const Json::Value &request, Json::Value &response) { - response = this->addToGroup(request[0u].asString(), request[1u].asString()); + (void)request; + response = this->listening(); } - - inline virtual void balanceAtI(const Json::Value& request, Json::Value& response) + inline virtual void setListeningI(const Json::Value &request, Json::Value &response) { - response = this->balanceAt(request[0u].asString()); + response = this->setListening(request[0u].asBool()); } - - inline virtual void blockByHashI(const Json::Value& request, Json::Value& response) + inline virtual void miningI(const Json::Value &request, Json::Value &response) { - response = this->blockByHash(request[0u].asString()); + (void)request; + response = this->mining(); } - - inline virtual void blockByNumberI(const Json::Value& request, Json::Value& response) + inline virtual void setMiningI(const Json::Value &request, Json::Value &response) { - response = this->blockByNumber(request[0u].asInt()); + response = this->setMining(request[0u].asBool()); } - - inline virtual void callI(const Json::Value& request, Json::Value& response) + inline virtual void gasPriceI(const Json::Value &request, Json::Value &response) { - response = this->call(request[0u]); + (void)request; + response = this->gasPrice(); } - - inline virtual void changedI(const Json::Value& request, Json::Value& response) + inline virtual void accountI(const Json::Value &request, Json::Value &response) { - response = this->changed(request[0u].asInt()); + (void)request; + response = this->account(); } - - inline virtual void codeAtI(const Json::Value& request, Json::Value& response) + inline virtual void accountsI(const Json::Value &request, Json::Value &response) { - response = this->codeAt(request[0u].asString()); + (void)request; + response = this->accounts(); } - - inline virtual void coinbaseI(const Json::Value& request, Json::Value& response) + inline virtual void peerCountI(const Json::Value &request, Json::Value &response) { - response = this->coinbase(); + (void)request; + response = this->peerCount(); } - - inline virtual void compileI(const Json::Value& request, Json::Value& response) + inline virtual void defaultBlockI(const Json::Value &request, Json::Value &response) { - response = this->compile(request[0u].asString()); + (void)request; + response = this->defaultBlock(); } - - inline virtual void countAtI(const Json::Value& request, Json::Value& response) + inline virtual void setDefaultBlockI(const Json::Value &request, Json::Value &response) { - response = this->countAt(request[0u].asString()); + response = this->setDefaultBlock(request[0u].asInt()); } - - inline virtual void defaultBlockI(const Json::Value& request, Json::Value& response) + inline virtual void numberI(const Json::Value &request, Json::Value &response) { - response = this->defaultBlock(); + (void)request; + response = this->number(); } - - inline virtual void gasPriceI(const Json::Value& request, Json::Value& response) + inline virtual void balanceAtI(const Json::Value &request, Json::Value &response) { - response = this->gasPrice(); + response = this->balanceAt(request[0u].asString()); } - - inline virtual void getI(const Json::Value& request, Json::Value& response) + inline virtual void stateAtI(const Json::Value &request, Json::Value &response) { - response = this->get(request[0u].asString(), request[1u].asString()); + response = this->stateAt(request[0u].asString(), request[1u].asString()); } - - inline virtual void getMessagesI(const Json::Value& request, Json::Value& response) + inline virtual void countAtI(const Json::Value &request, Json::Value &response) { - response = this->getMessages(request[0u].asInt()); + response = this->countAt(request[0u].asString()); } - - inline virtual void getStringI(const Json::Value& request, Json::Value& response) + inline virtual void codeAtI(const Json::Value &request, Json::Value &response) { - response = this->getString(request[0u].asString(), request[1u].asString()); + response = this->codeAt(request[0u].asString()); } - - inline virtual void haveIdentityI(const Json::Value& request, Json::Value& response) + inline virtual void transactI(const Json::Value &request, Json::Value &response) { - response = this->haveIdentity(request[0u].asString()); + response = this->transact(request[0u]); } - - inline virtual void listeningI(const Json::Value& request, Json::Value& response) + inline virtual void callI(const Json::Value &request, Json::Value &response) { - response = this->listening(); + response = this->call(request[0u]); } - - inline virtual void miningI(const Json::Value& request, Json::Value& response) + inline virtual void blockByHashI(const Json::Value &request, Json::Value &response) { - response = this->mining(); + response = this->blockByHash(request[0u].asString()); } - - inline virtual void newFilterI(const Json::Value& request, Json::Value& response) + inline virtual void blockByNumberI(const Json::Value &request, Json::Value &response) { - response = this->newFilter(request[0u]); + response = this->blockByNumber(request[0u].asInt()); } - - inline virtual void newFilterStringI(const Json::Value& request, Json::Value& response) + inline virtual void transactionByHashI(const Json::Value &request, Json::Value &response) { - response = this->newFilterString(request[0u].asString()); + response = this->transactionByHash(request[0u].asString(), request[1u].asInt()); } - - inline virtual void newGroupI(const Json::Value& request, Json::Value& response) + inline virtual void transactionByNumberI(const Json::Value &request, Json::Value &response) { - response = this->newGroup(request[0u].asString(), request[1u].asString()); + response = this->transactionByNumber(request[0u].asInt(), request[1u].asInt()); } - - inline virtual void newIdentityI(const Json::Value& request, Json::Value& response) + inline virtual void uncleByHashI(const Json::Value &request, Json::Value &response) { - response = this->newIdentity(); + response = this->uncleByHash(request[0u].asString(), request[1u].asInt()); } - - inline virtual void numberI(const Json::Value& request, Json::Value& response) + inline virtual void uncleByNumberI(const Json::Value &request, Json::Value &response) { - response = this->number(); + response = this->uncleByNumber(request[0u].asInt(), request[1u].asInt()); } - - inline virtual void peerCountI(const Json::Value& request, Json::Value& response) + inline virtual void compileI(const Json::Value &request, Json::Value &response) { - response = this->peerCount(); + response = this->compile(request[0u].asString()); } - - inline virtual void postI(const Json::Value& request, Json::Value& response) + inline virtual void newFilterI(const Json::Value &request, Json::Value &response) { - response = this->post(request[0u]); + response = this->newFilter(request[0u]); } - - inline virtual void putI(const Json::Value& request, Json::Value& response) + inline virtual void newFilterStringI(const Json::Value &request, Json::Value &response) { - response = this->put(request[0u].asString(), request[1u].asString(), request[2u].asString()); + response = this->newFilterString(request[0u].asString()); } - - inline virtual void putStringI(const Json::Value& request, Json::Value& response) + inline virtual void uninstallFilterI(const Json::Value &request, Json::Value &response) { - response = this->putString(request[0u].asString(), request[1u].asString(), request[2u].asString()); + response = this->uninstallFilter(request[0u].asInt()); } - - inline virtual void setCoinbaseI(const Json::Value& request, Json::Value& response) + inline virtual void changedI(const Json::Value &request, Json::Value &response) { - response = this->setCoinbase(request[0u].asString()); + response = this->changed(request[0u].asInt()); } - - inline virtual void setDefaultBlockI(const Json::Value& request, Json::Value& response) + inline virtual void getMessagesI(const Json::Value &request, Json::Value &response) { - response = this->setDefaultBlock(request[0u].asInt()); + response = this->getMessages(request[0u].asInt()); } - - inline virtual void setListeningI(const Json::Value& request, Json::Value& response) + inline virtual void putI(const Json::Value &request, Json::Value &response) { - response = this->setListening(request[0u].asBool()); + response = this->put(request[0u].asString(), request[1u].asString(), request[2u].asString()); } - - inline virtual void setMiningI(const Json::Value& request, Json::Value& response) + inline virtual void getI(const Json::Value &request, Json::Value &response) { - response = this->setMining(request[0u].asBool()); + response = this->get(request[0u].asString(), request[1u].asString()); } - - inline virtual void shhChangedI(const Json::Value& request, Json::Value& response) + inline virtual void putStringI(const Json::Value &request, Json::Value &response) { - response = this->shhChanged(request[0u].asInt()); + response = this->putString(request[0u].asString(), request[1u].asString(), request[2u].asString()); } - - inline virtual void shhNewFilterI(const Json::Value& request, Json::Value& response) + inline virtual void getStringI(const Json::Value &request, Json::Value &response) { - response = this->shhNewFilter(request[0u]); + response = this->getString(request[0u].asString(), request[1u].asString()); } - - inline virtual void shhUninstallFilterI(const Json::Value& request, Json::Value& response) + inline virtual void postI(const Json::Value &request, Json::Value &response) { - response = this->shhUninstallFilter(request[0u].asInt()); + response = this->post(request[0u]); } - - inline virtual void stateAtI(const Json::Value& request, Json::Value& response) + inline virtual void newIdentityI(const Json::Value &request, Json::Value &response) { - response = this->stateAt(request[0u].asString(), request[1u].asString()); + (void)request; + response = this->newIdentity(); } - - inline virtual void transactI(const Json::Value& request, Json::Value& response) + inline virtual void haveIdentityI(const Json::Value &request, Json::Value &response) { - response = this->transact(request[0u]); + response = this->haveIdentity(request[0u].asString()); } - - inline virtual void transactionByHashI(const Json::Value& request, Json::Value& response) + inline virtual void newGroupI(const Json::Value &request, Json::Value &response) { - response = this->transactionByHash(request[0u].asString(), request[1u].asInt()); + response = this->newGroup(request[0u].asString(), request[1u].asString()); } - - inline virtual void transactionByNumberI(const Json::Value& request, Json::Value& response) + inline virtual void addToGroupI(const Json::Value &request, Json::Value &response) { - response = this->transactionByNumber(request[0u].asInt(), request[1u].asInt()); + response = this->addToGroup(request[0u].asString(), request[1u].asString()); } - - inline virtual void uncleByHashI(const Json::Value& request, Json::Value& response) + inline virtual void shhNewFilterI(const Json::Value &request, Json::Value &response) { - response = this->uncleByHash(request[0u].asString(), request[1u].asInt()); + response = this->shhNewFilter(request[0u]); } - - inline virtual void uncleByNumberI(const Json::Value& request, Json::Value& response) + inline virtual void shhUninstallFilterI(const Json::Value &request, Json::Value &response) { - response = this->uncleByNumber(request[0u].asInt(), request[1u].asInt()); + response = this->shhUninstallFilter(request[0u].asInt()); } - - inline virtual void uninstallFilterI(const Json::Value& request, Json::Value& response) + inline virtual void shhChangedI(const Json::Value &request, Json::Value &response) { - response = this->uninstallFilter(request[0u].asInt()); + response = this->shhChanged(request[0u].asInt()); } - - - virtual std::string account() = 0; - virtual Json::Value accounts() = 0; - virtual std::string addToGroup(const std::string& param1, const std::string& param2) = 0; - virtual std::string balanceAt(const std::string& param1) = 0; - virtual Json::Value blockByHash(const std::string& param1) = 0; - virtual Json::Value blockByNumber(const int& param1) = 0; - virtual std::string call(const Json::Value& param1) = 0; - virtual bool changed(const int& param1) = 0; - virtual std::string codeAt(const std::string& param1) = 0; virtual std::string coinbase() = 0; - virtual std::string compile(const std::string& param1) = 0; - virtual double countAt(const std::string& param1) = 0; - virtual int defaultBlock() = 0; - virtual std::string gasPrice() = 0; - virtual std::string get(const std::string& param1, const std::string& param2) = 0; - virtual Json::Value getMessages(const int& param1) = 0; - virtual std::string getString(const std::string& param1, const std::string& param2) = 0; - virtual bool haveIdentity(const std::string& param1) = 0; + virtual bool setCoinbase(const std::string& param1) = 0; virtual bool listening() = 0; + virtual bool setListening(const bool& param1) = 0; virtual bool mining() = 0; - virtual int newFilter(const Json::Value& param1) = 0; - virtual int newFilterString(const std::string& param1) = 0; - virtual std::string newGroup(const std::string& param1, const std::string& param2) = 0; - virtual std::string newIdentity() = 0; - virtual int number() = 0; + virtual bool setMining(const bool& param1) = 0; + virtual std::string gasPrice() = 0; + virtual std::string account() = 0; + virtual Json::Value accounts() = 0; virtual int peerCount() = 0; - virtual bool post(const Json::Value& param1) = 0; - virtual bool put(const std::string& param1, const std::string& param2, const std::string& param3) = 0; - virtual bool putString(const std::string& param1, const std::string& param2, const std::string& param3) = 0; - virtual bool setCoinbase(const std::string& param1) = 0; + virtual int defaultBlock() = 0; virtual bool setDefaultBlock(const int& param1) = 0; - virtual bool setListening(const bool& param1) = 0; - virtual bool setMining(const bool& param1) = 0; - virtual Json::Value shhChanged(const int& param1) = 0; - virtual int shhNewFilter(const Json::Value& param1) = 0; - virtual bool shhUninstallFilter(const int& param1) = 0; + virtual int number() = 0; + virtual std::string balanceAt(const std::string& param1) = 0; virtual std::string stateAt(const std::string& param1, const std::string& param2) = 0; + virtual double countAt(const std::string& param1) = 0; + virtual std::string codeAt(const std::string& param1) = 0; virtual std::string transact(const Json::Value& param1) = 0; + virtual std::string call(const Json::Value& param1) = 0; + virtual Json::Value blockByHash(const std::string& param1) = 0; + virtual Json::Value blockByNumber(const int& param1) = 0; virtual Json::Value transactionByHash(const std::string& param1, const int& param2) = 0; virtual Json::Value transactionByNumber(const int& param1, const int& param2) = 0; virtual Json::Value uncleByHash(const std::string& param1, const int& param2) = 0; virtual Json::Value uncleByNumber(const int& param1, const int& param2) = 0; + virtual std::string compile(const std::string& param1) = 0; + virtual int newFilter(const Json::Value& param1) = 0; + virtual int newFilterString(const std::string& param1) = 0; virtual bool uninstallFilter(const int& param1) = 0; - + virtual bool changed(const int& param1) = 0; + virtual Json::Value getMessages(const int& param1) = 0; + virtual bool put(const std::string& param1, const std::string& param2, const std::string& param3) = 0; + virtual std::string get(const std::string& param1, const std::string& param2) = 0; + virtual bool putString(const std::string& param1, const std::string& param2, const std::string& param3) = 0; + virtual std::string getString(const std::string& param1, const std::string& param2) = 0; + virtual bool post(const Json::Value& param1) = 0; + virtual std::string newIdentity() = 0; + virtual bool haveIdentity(const std::string& param1) = 0; + virtual std::string newGroup(const std::string& param1, const std::string& param2) = 0; + virtual std::string addToGroup(const std::string& param1, const std::string& param2) = 0; + virtual int shhNewFilter(const Json::Value& param1) = 0; + virtual bool shhUninstallFilter(const int& param1) = 0; + virtual Json::Value shhChanged(const int& param1) = 0; }; -#endif //_ABSTRACTWEBTHREESTUBSERVER_H_ + +#endif //JSONRPC_CPP_ABSTRACTWEBTHREESTUBSERVER_H_ diff --git a/libweb3jsonrpc/spec.json b/libweb3jsonrpc/spec.json index 1e7065970..aea50adf9 100644 --- a/libweb3jsonrpc/spec.json +++ b/libweb3jsonrpc/spec.json @@ -1,55 +1,55 @@ [ - { "method": "coinbase", "params": [], "order": [], "returns" : "" }, - { "method": "setCoinbase", "params": [""], "order": [], "returns" : true }, - { "method": "listening", "params": [], "order": [], "returns" : false }, - { "method": "setListening", "params": [false], "order" : [], "returns" : true }, - { "method": "mining", "params": [], "order": [], "returns" : false }, - { "method": "setMining", "params": [false], "order" : [], "returns" : true }, - { "method": "gasPrice", "params": [], "order": [], "returns" : "" }, - { "method": "account", "params": [], "order": [], "returns" : "" }, - { "method": "accounts", "params": [], "order": [], "returns" : [] }, - { "method": "peerCount", "params": [], "order": [], "returns" : 0 }, - { "method": "defaultBlock", "params": [], "order": [], "returns" : 0}, - { "method": "setDefaultBlock", "params": [0], "order": [], "returns" : true}, - { "method": "number", "params": [], "order": [], "returns" : 0}, - - { "method": "balanceAt", "params": [""], "order": [], "returns" : ""}, - { "method": "stateAt", "params": ["", ""], "order": [], "returns": ""}, - { "method": "countAt", "params": [""], "order": [], "returns" : 0.0}, - { "method": "codeAt", "params": [""], "order": [], "returns": ""}, - - { "method": "transact", "params": [{}], "order": [], "returns": ""}, - { "method": "call", "params": [{}], "order": [], "returns": ""}, - - { "method": "blockByHash", "params": [""],"order": [], "returns": {}}, - { "method": "blockByNumber", "params": [0],"order": [], "returns": {}}, - { "method": "transactionByHash", "params": ["", 0], "order": [], "returns": {}}, - { "method": "transactionByNumber", "params": [0, 0], "order": [], "returns": {}}, - { "method": "uncleByHash", "params": ["", 0], "order": [], "returns": {}}, - { "method": "uncleByNumber", "params": [0, 0], "order": [], "returns": {}}, - - { "method": "compile", "params": [""], "order": [], "returns": ""}, - - { "method": "newFilter", "params": [{}], "order": [], "returns": 0}, - { "method": "newFilterString", "params": [""], "order": [], "returns": 0}, - { "method": "uninstallFilter", "params": [0], "order": [], "returns": true}, - { "method": "changed", "params": [0], "order": [], "returns": false}, - { "method": "getMessages", "params": [0], "order": [], "returns": []}, - - { "method": "put", "params": ["", "", ""], "order": [], "returns": true}, - { "method": "get", "params": ["", ""], "order": [], "returns": ""}, - { "method": "putString", "params": ["", "", ""], "order": [], "returns": true}, - { "method": "getString", "params": ["", ""], "order": [], "returns": ""}, - - { "method": "post", "params": [{}], "order": [], "returns": true}, - { "method": "newIdentity", "params": [], "order": [], "returns": ""}, - { "method": "haveIdentity", "params": [""], "order": [], "returns": false}, - { "method": "newGroup", "params": ["", ""], "order": [], "returns": ""}, - { "method": "addToGroup", "params": ["", ""], "order": [], "returns": ""}, + { "name": "coinbase", "params": [], "order": [], "returns" : "" }, + { "name": "setCoinbase", "params": [""], "order": [], "returns" : true }, + { "name": "listening", "params": [], "order": [], "returns" : false }, + { "name": "setListening", "params": [false], "order" : [], "returns" : true }, + { "name": "mining", "params": [], "order": [], "returns" : false }, + { "name": "setMining", "params": [false], "order" : [], "returns" : true }, + { "name": "gasPrice", "params": [], "order": [], "returns" : "" }, + { "name": "account", "params": [], "order": [], "returns" : "" }, + { "name": "accounts", "params": [], "order": [], "returns" : [] }, + { "name": "peerCount", "params": [], "order": [], "returns" : 0 }, + { "name": "defaultBlock", "params": [], "order": [], "returns" : 0}, + { "name": "setDefaultBlock", "params": [0], "order": [], "returns" : true}, + { "name": "number", "params": [], "order": [], "returns" : 0}, + + { "name": "balanceAt", "params": [""], "order": [], "returns" : ""}, + { "name": "stateAt", "params": ["", ""], "order": [], "returns": ""}, + { "name": "countAt", "params": [""], "order": [], "returns" : 0.0}, + { "name": "codeAt", "params": [""], "order": [], "returns": ""}, + + { "name": "transact", "params": [{}], "order": [], "returns": ""}, + { "name": "call", "params": [{}], "order": [], "returns": ""}, + + { "name": "blockByHash", "params": [""],"order": [], "returns": {}}, + { "name": "blockByNumber", "params": [0],"order": [], "returns": {}}, + { "name": "transactionByHash", "params": ["", 0], "order": [], "returns": {}}, + { "name": "transactionByNumber", "params": [0, 0], "order": [], "returns": {}}, + { "name": "uncleByHash", "params": ["", 0], "order": [], "returns": {}}, + { "name": "uncleByNumber", "params": [0, 0], "order": [], "returns": {}}, + + { "name": "compile", "params": [""], "order": [], "returns": ""}, + + { "name": "newFilter", "params": [{}], "order": [], "returns": 0}, + { "name": "newFilterString", "params": [""], "order": [], "returns": 0}, + { "name": "uninstallFilter", "params": [0], "order": [], "returns": true}, + { "name": "changed", "params": [0], "order": [], "returns": false}, + { "name": "getMessages", "params": [0], "order": [], "returns": []}, + + { "name": "put", "params": ["", "", ""], "order": [], "returns": true}, + { "name": "get", "params": ["", ""], "order": [], "returns": ""}, + { "name": "putString", "params": ["", "", ""], "order": [], "returns": true}, + { "name": "getString", "params": ["", ""], "order": [], "returns": ""}, + + { "name": "post", "params": [{}], "order": [], "returns": true}, + { "name": "newIdentity", "params": [], "order": [], "returns": ""}, + { "name": "haveIdentity", "params": [""], "order": [], "returns": false}, + { "name": "newGroup", "params": ["", ""], "order": [], "returns": ""}, + { "name": "addToGroup", "params": ["", ""], "order": [], "returns": ""}, - { "method": "shhNewFilter", "params": [{}], "order": [], "returns": 0}, - { "method": "shhUninstallFilter", "params": [0], "order": [], "returns": true}, - { "method": "shhChanged", "params": [0], "order": [], "returns": []} + { "name": "shhNewFilter", "params": [{}], "order": [], "returns": 0}, + { "name": "shhUninstallFilter", "params": [0], "order": [], "returns": true}, + { "name": "shhChanged", "params": [0], "order": [], "returns": []} ] diff --git a/neth/main.cpp b/neth/main.cpp index 4e3a0f40a..8512cf77b 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -27,7 +27,7 @@ #include #include #if ETH_JSONRPC -#include +#include #endif #include #include diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a11c9fa16..63094fa23 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -18,6 +18,7 @@ target_link_libraries(testeth ${CRYPTOPP_LS}) target_link_libraries(testeth webthree) if(JSONRPC_LS) target_link_libraries(testeth web3jsonrpc) +target_link_libraries(testeth ${JSONRPC_CLIENT_LS}) endif() target_link_libraries(createRandomTest ethereum) diff --git a/test/jsonrpc.cpp b/test/jsonrpc.cpp index 033339ec2..f261a5164 100644 --- a/test/jsonrpc.cpp +++ b/test/jsonrpc.cpp @@ -29,8 +29,10 @@ #include #include #include -#include -#include +#include +#include +//#include +//#include #include #include "JsonSpiritHeaders.h" #include "TestHelper.h" @@ -54,7 +56,8 @@ dev::WebThreeDirect web3(name, dbPath, true, s, np); unique_ptr jsonrpcServer; unique_ptr jsonrpcClient; - +jsonrpc::HttpClient httpClient("http://localhost:8080"); + struct JsonrpcFixture { JsonrpcFixture() { @@ -66,7 +69,7 @@ struct JsonrpcFixture { jsonrpcServer->setIdentities({}); jsonrpcServer->StartListening(); - jsonrpcClient = unique_ptr(new WebThreeStubClient(new jsonrpc::HttpClient("http://localhost:8080"))); + jsonrpcClient = unique_ptr(new WebThreeStubClient(httpClient)); } ~JsonrpcFixture() { diff --git a/test/webthreestubclient.h b/test/webthreestubclient.h index 6beee5bb6..abe146efc 100644 --- a/test/webthreestubclient.h +++ b/test/webthreestubclient.h @@ -1,587 +1,460 @@ /** - * THIS FILE IS GENERATED BY jsonrpcstub, DO NOT CHANGE IT!!!!! + * This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY! */ -#ifndef _WEBTHREESTUBCLIENT_H_ -#define _WEBTHREESTUBCLIENT_H_ +#ifndef JSONRPC_CPP_STUB_WEBTHREESTUBCLIENT_H_ +#define JSONRPC_CPP_STUB_WEBTHREESTUBCLIENT_H_ -#include +#include -class WebThreeStubClient +class WebThreeStubClient : public jsonrpc::Client { public: - WebThreeStubClient(jsonrpc::AbstractClientConnector* conn) - { - this->client = new jsonrpc::Client(conn); - } - ~WebThreeStubClient() - { - delete this->client; - } + WebThreeStubClient(jsonrpc::IClientConnector &conn) : jsonrpc::Client(conn) {} - std::string account() throw (jsonrpc::JsonRpcException) + std::string coinbase() throw (jsonrpc::JsonRpcException) { Json::Value p; p = Json::nullValue; - Json::Value result = this->client->CallMethod("account",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + Json::Value result = this->CallMethod("coinbase",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - Json::Value accounts() throw (jsonrpc::JsonRpcException) + bool setCoinbase(const std::string& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; - p = Json::nullValue; - Json::Value result = this->client->CallMethod("accounts",p); - if (result.isArray()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + p.append(param1); + Json::Value result = this->CallMethod("setCoinbase",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - std::string addToGroup(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + bool listening() throw (jsonrpc::JsonRpcException) { Json::Value p; - p.append(param1); -p.append(param2); - - Json::Value result = this->client->CallMethod("addToGroup",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + p = Json::nullValue; + Json::Value result = this->CallMethod("listening",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - std::string balanceAt(const std::string& param1) throw (jsonrpc::JsonRpcException) + bool setListening(const bool& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); - - Json::Value result = this->client->CallMethod("balanceAt",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + Json::Value result = this->CallMethod("setListening",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - Json::Value blockByHash(const std::string& param1) throw (jsonrpc::JsonRpcException) + bool mining() throw (jsonrpc::JsonRpcException) { Json::Value p; - p.append(param1); - - Json::Value result = this->client->CallMethod("blockByHash",p); - if (result.isObject()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + p = Json::nullValue; + Json::Value result = this->CallMethod("mining",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - Json::Value blockByNumber(const int& param1) throw (jsonrpc::JsonRpcException) + bool setMining(const bool& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); - - Json::Value result = this->client->CallMethod("blockByNumber",p); - if (result.isObject()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + Json::Value result = this->CallMethod("setMining",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - std::string call(const Json::Value& param1) throw (jsonrpc::JsonRpcException) + std::string gasPrice() throw (jsonrpc::JsonRpcException) { Json::Value p; - p.append(param1); - - Json::Value result = this->client->CallMethod("call",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + p = Json::nullValue; + Json::Value result = this->CallMethod("gasPrice",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - bool changed(const int& param1) throw (jsonrpc::JsonRpcException) + std::string account() throw (jsonrpc::JsonRpcException) { Json::Value p; - p.append(param1); - - Json::Value result = this->client->CallMethod("changed",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + p = Json::nullValue; + Json::Value result = this->CallMethod("account",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - std::string codeAt(const std::string& param1) throw (jsonrpc::JsonRpcException) + Json::Value accounts() throw (jsonrpc::JsonRpcException) { Json::Value p; - p.append(param1); - - Json::Value result = this->client->CallMethod("codeAt",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + p = Json::nullValue; + Json::Value result = this->CallMethod("accounts",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - std::string coinbase() throw (jsonrpc::JsonRpcException) + int peerCount() throw (jsonrpc::JsonRpcException) { Json::Value p; p = Json::nullValue; - Json::Value result = this->client->CallMethod("coinbase",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + Json::Value result = this->CallMethod("peerCount",p); + if (result.isInt()) + return result.asInt(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - std::string compile(const std::string& param1) throw (jsonrpc::JsonRpcException) + int defaultBlock() throw (jsonrpc::JsonRpcException) { Json::Value p; - p.append(param1); - - Json::Value result = this->client->CallMethod("compile",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + p = Json::nullValue; + Json::Value result = this->CallMethod("defaultBlock",p); + if (result.isInt()) + return result.asInt(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - double countAt(const std::string& param1) throw (jsonrpc::JsonRpcException) + bool setDefaultBlock(const int& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); - - Json::Value result = this->client->CallMethod("countAt",p); - if (result.isDouble()) - return result.asDouble(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + Json::Value result = this->CallMethod("setDefaultBlock",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - int defaultBlock() throw (jsonrpc::JsonRpcException) + int number() throw (jsonrpc::JsonRpcException) { Json::Value p; p = Json::nullValue; - Json::Value result = this->client->CallMethod("defaultBlock",p); - if (result.isInt()) - return result.asInt(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + Json::Value result = this->CallMethod("number",p); + if (result.isInt()) + return result.asInt(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - std::string gasPrice() throw (jsonrpc::JsonRpcException) + std::string balanceAt(const std::string& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; - p = Json::nullValue; - Json::Value result = this->client->CallMethod("gasPrice",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + p.append(param1); + Json::Value result = this->CallMethod("balanceAt",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - std::string get(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + std::string stateAt(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); -p.append(param2); - - Json::Value result = this->client->CallMethod("get",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + p.append(param2); + Json::Value result = this->CallMethod("stateAt",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - Json::Value getMessages(const int& param1) throw (jsonrpc::JsonRpcException) + double countAt(const std::string& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); - - Json::Value result = this->client->CallMethod("getMessages",p); - if (result.isArray()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + Json::Value result = this->CallMethod("countAt",p); + if (result.isDouble()) + return result.asDouble(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - std::string getString(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + std::string codeAt(const std::string& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); -p.append(param2); - - Json::Value result = this->client->CallMethod("getString",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + Json::Value result = this->CallMethod("codeAt",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - bool haveIdentity(const std::string& param1) throw (jsonrpc::JsonRpcException) + std::string transact(const Json::Value& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); - - Json::Value result = this->client->CallMethod("haveIdentity",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + Json::Value result = this->CallMethod("transact",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - bool listening() throw (jsonrpc::JsonRpcException) + std::string call(const Json::Value& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; - p = Json::nullValue; - Json::Value result = this->client->CallMethod("listening",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + p.append(param1); + Json::Value result = this->CallMethod("call",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - bool mining() throw (jsonrpc::JsonRpcException) + Json::Value blockByHash(const std::string& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; - p = Json::nullValue; - Json::Value result = this->client->CallMethod("mining",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + p.append(param1); + Json::Value result = this->CallMethod("blockByHash",p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - int newFilter(const Json::Value& param1) throw (jsonrpc::JsonRpcException) + Json::Value blockByNumber(const int& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); - - Json::Value result = this->client->CallMethod("newFilter",p); - if (result.isInt()) - return result.asInt(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + Json::Value result = this->CallMethod("blockByNumber",p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - int newFilterString(const std::string& param1) throw (jsonrpc::JsonRpcException) + Json::Value transactionByHash(const std::string& param1, const int& param2) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); - - Json::Value result = this->client->CallMethod("newFilterString",p); - if (result.isInt()) - return result.asInt(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + p.append(param2); + Json::Value result = this->CallMethod("transactionByHash",p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - std::string newGroup(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + Json::Value transactionByNumber(const int& param1, const int& param2) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); -p.append(param2); - - Json::Value result = this->client->CallMethod("newGroup",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + p.append(param2); + Json::Value result = this->CallMethod("transactionByNumber",p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - std::string newIdentity() throw (jsonrpc::JsonRpcException) + Json::Value uncleByHash(const std::string& param1, const int& param2) throw (jsonrpc::JsonRpcException) { Json::Value p; - p = Json::nullValue; - Json::Value result = this->client->CallMethod("newIdentity",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("uncleByHash",p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - int number() throw (jsonrpc::JsonRpcException) + Json::Value uncleByNumber(const int& param1, const int& param2) throw (jsonrpc::JsonRpcException) { Json::Value p; - p = Json::nullValue; - Json::Value result = this->client->CallMethod("number",p); - if (result.isInt()) - return result.asInt(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("uncleByNumber",p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - int peerCount() throw (jsonrpc::JsonRpcException) + std::string compile(const std::string& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; - p = Json::nullValue; - Json::Value result = this->client->CallMethod("peerCount",p); - if (result.isInt()) - return result.asInt(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + p.append(param1); + Json::Value result = this->CallMethod("compile",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - bool post(const Json::Value& param1) throw (jsonrpc::JsonRpcException) + int newFilter(const Json::Value& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); - - Json::Value result = this->client->CallMethod("post",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + Json::Value result = this->CallMethod("newFilter",p); + if (result.isInt()) + return result.asInt(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - bool put(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) + int newFilterString(const std::string& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); -p.append(param2); -p.append(param3); - - Json::Value result = this->client->CallMethod("put",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + Json::Value result = this->CallMethod("newFilterString",p); + if (result.isInt()) + return result.asInt(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - bool putString(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) + bool uninstallFilter(const int& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); -p.append(param2); -p.append(param3); - - Json::Value result = this->client->CallMethod("putString",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + Json::Value result = this->CallMethod("uninstallFilter",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - bool setCoinbase(const std::string& param1) throw (jsonrpc::JsonRpcException) + bool changed(const int& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); - - Json::Value result = this->client->CallMethod("setCoinbase",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + Json::Value result = this->CallMethod("changed",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - bool setDefaultBlock(const int& param1) throw (jsonrpc::JsonRpcException) + Json::Value getMessages(const int& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); - - Json::Value result = this->client->CallMethod("setDefaultBlock",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + Json::Value result = this->CallMethod("getMessages",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - bool setListening(const bool& param1) throw (jsonrpc::JsonRpcException) + bool put(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); - - Json::Value result = this->client->CallMethod("setListening",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + p.append(param2); + p.append(param3); + Json::Value result = this->CallMethod("put",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - bool setMining(const bool& param1) throw (jsonrpc::JsonRpcException) + std::string get(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); - - Json::Value result = this->client->CallMethod("setMining",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + p.append(param2); + Json::Value result = this->CallMethod("get",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - Json::Value shhChanged(const int& param1) throw (jsonrpc::JsonRpcException) + bool putString(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); - - Json::Value result = this->client->CallMethod("shhChanged",p); - if (result.isArray()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + p.append(param2); + p.append(param3); + Json::Value result = this->CallMethod("putString",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - int shhNewFilter(const Json::Value& param1) throw (jsonrpc::JsonRpcException) + std::string getString(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); - - Json::Value result = this->client->CallMethod("shhNewFilter",p); - if (result.isInt()) - return result.asInt(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + p.append(param2); + Json::Value result = this->CallMethod("getString",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - bool shhUninstallFilter(const int& param1) throw (jsonrpc::JsonRpcException) + bool post(const Json::Value& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); - - Json::Value result = this->client->CallMethod("shhUninstallFilter",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + Json::Value result = this->CallMethod("post",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - std::string stateAt(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + std::string newIdentity() throw (jsonrpc::JsonRpcException) { Json::Value p; - p.append(param1); -p.append(param2); - - Json::Value result = this->client->CallMethod("stateAt",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + p = Json::nullValue; + Json::Value result = this->CallMethod("newIdentity",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - std::string transact(const Json::Value& param1) throw (jsonrpc::JsonRpcException) + bool haveIdentity(const std::string& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); - - Json::Value result = this->client->CallMethod("transact",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + Json::Value result = this->CallMethod("haveIdentity",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - Json::Value transactionByHash(const std::string& param1, const int& param2) throw (jsonrpc::JsonRpcException) + std::string newGroup(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); -p.append(param2); - - Json::Value result = this->client->CallMethod("transactionByHash",p); - if (result.isObject()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + p.append(param2); + Json::Value result = this->CallMethod("newGroup",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - Json::Value transactionByNumber(const int& param1, const int& param2) throw (jsonrpc::JsonRpcException) + std::string addToGroup(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); -p.append(param2); - - Json::Value result = this->client->CallMethod("transactionByNumber",p); - if (result.isObject()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + p.append(param2); + Json::Value result = this->CallMethod("addToGroup",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - Json::Value uncleByHash(const std::string& param1, const int& param2) throw (jsonrpc::JsonRpcException) + int shhNewFilter(const Json::Value& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); -p.append(param2); - - Json::Value result = this->client->CallMethod("uncleByHash",p); - if (result.isObject()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + Json::Value result = this->CallMethod("shhNewFilter",p); + if (result.isInt()) + return result.asInt(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - Json::Value uncleByNumber(const int& param1, const int& param2) throw (jsonrpc::JsonRpcException) + bool shhUninstallFilter(const int& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); -p.append(param2); - - Json::Value result = this->client->CallMethod("uncleByNumber",p); - if (result.isObject()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + Json::Value result = this->CallMethod("shhUninstallFilter",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - bool uninstallFilter(const int& param1) throw (jsonrpc::JsonRpcException) + Json::Value shhChanged(const int& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; p.append(param1); - - Json::Value result = this->client->CallMethod("uninstallFilter",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - + Json::Value result = this->CallMethod("shhChanged",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - - private: - jsonrpc::Client* client; }; -#endif //_WEBTHREESTUBCLIENT_H_ + +#endif //JSONRPC_CPP_WEBTHREESTUBCLIENT_H_ From 7c81eca7e0fbe8c53e4abf93a4c40e3eaacb45f4 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Mon, 3 Nov 2014 17:00:39 +0100 Subject: [PATCH 006/277] updated README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 23a202510..8b5ff903d 100644 --- a/README.md +++ b/README.md @@ -36,5 +36,5 @@ Please read [CodingStandards.txt](CodingStandards.txt) thoroughly before making libweb3jsonrpc/abstractwebthreestubserver.h is autogenerated from the jsonrpcstub executable that comes with the libjsonrpc library (json-rpc-cpp project). It shouldn't be maually altered. ```bash -jsonrpcstub -s -c spec.json WebThreeStub +jsonrpcstub spec.json --cpp-server=AbstractWebThreeStubServer ``` From 23c39172f8dc3072cd908724f92a1f4e6ef44187 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 4 Nov 2014 11:15:16 +0100 Subject: [PATCH 007/277] little cleanup after upgrading jsonrpc --- CMakeLists.txt | 4 +- cmake/EthDependenciesDeprecated.cmake | 68 ++++++++++++++------------- eth/CMakeLists.txt | 2 +- eth/main.cpp | 1 - libqethereum/CMakeLists.txt | 2 +- libqethereum/QEthereum.h | 1 - libweb3jsonrpc/CMakeLists.txt | 2 +- libweb3jsonrpc/CorsHttpServer.h | 1 - libweb3jsonrpc/WebThreeStubServer.h | 1 - neth/CMakeLists.txt | 2 +- test/CMakeLists.txt | 2 +- test/jsonrpc.cpp | 2 - 12 files changed, 42 insertions(+), 46 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b4aa2352f..5e99e1c41 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -119,7 +119,7 @@ endif() add_subdirectory(lllc) add_subdirectory(solc) add_subdirectory(sc) -if (JSONRPC_LS) +if (JSONRPC_SERVER_LS) add_subdirectory(libweb3jsonrpc) endif() if (NOT LANGUAGES) @@ -150,7 +150,7 @@ if (NOT LANGUAGES) if ("${TARGET_PLATFORM}" STREQUAL "w64") cmake_policy(SET CMP0020 NEW) endif () - if (NOT JSONRPC_LS) + if (NOT JSONRPC_SERVER_LS) message(FATAL_ERROR "Alethzero requires jsonrpc.") endif() diff --git a/cmake/EthDependenciesDeprecated.cmake b/cmake/EthDependenciesDeprecated.cmake index d815bef3e..8c6d07e48 100644 --- a/cmake/EthDependenciesDeprecated.cmake +++ b/cmake/EthDependenciesDeprecated.cmake @@ -125,48 +125,50 @@ else() message(STATUS "Failed to find the miniupnpc headers!") endif () - find_path( JSONRPC_ID jsonrpccpp/server.h - /usr/include - /usr/local/include - ) + find_path( JSONRPC_ID jsonrpccpp/server.h + /usr/include + /usr/local/include + ) if ( JSONRPC_ID ) message(STATUS "Found jsonrpc headers") - find_library( JSONRPC_LS NAMES jsonrpccpp-server + + find_library( JSONCPP_LS NAMES jsoncpp + /usr/lib + /usr/local/lib + /opt/local/lib + /usr/lib/*/ + ) + + find_library( JSONRPC_SERVER_LS NAMES jsonrpccpp-server PATHS /usr/lib /usr/local/lib /opt/local/lib /usr/lib/*/ ) - - find_library( JSONRPC_COMMON_LS NAMES jsonrpccpp-common - PATHS - /usr/lib - /usr/local/lib - /opt/local/lib - /usr/lib/*/ - ) - - find_library( JSONCPP_LS NAMES jsoncpp - /usr/lib - /usr/local/lib - /opt/local/lib - /usr/lib/*/ - ) - - find_library( JSONRPC_CLIENT_LS NAMES jsonrpccpp-client - PATHS - /usr/lib/ - /usr/local/lib - /opt/local/lib - /usr/lib/*/ - ) - - if ( JSONRPC_LS AND JSONRPC_COMMON_LS ) - message(STATUS "Found jsonrpc library: ${JSONRPC_LS}") - message(STATUS "Found jsonrpc-common library: ${JSONRPC_COMMON_LS}") - add_definitions(-DETH_JSONRPC) + + find_library( JSONRPC_COMMON_LS NAMES jsonrpccpp-common + PATHS + /usr/lib + /usr/local/lib + /opt/local/lib + /usr/lib/*/ + ) + + find_library( JSONRPC_CLIENT_LS NAMES jsonrpccpp-client + PATHS + /usr/lib/ + /usr/local/lib + /opt/local/lib + /usr/lib/*/ + ) + + if ( JSONRPC_SERVER_LS AND JSONRPC_COMMON_LS ) + message(STATUS "Found jsonrpc-server library: ${JSONRPC_SERVER_LS}") + message(STATUS "Found jsonrpc-client library: ${JSONRPC_CLIENT_LS}") + message(STATUS "Found jsonrpc-common library: ${JSONRPC_COMMON_LS}") + add_definitions(-DETH_JSONRPC) else () message(STATUS "Failed to find the jsonrpc library!") endif () diff --git a/eth/CMakeLists.txt b/eth/CMakeLists.txt index 7c997b256..1d6325ecc 100644 --- a/eth/CMakeLists.txt +++ b/eth/CMakeLists.txt @@ -17,7 +17,7 @@ if(MINIUPNPC_LS) endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) -if(JSONRPC_LS) +if(JSONRPC_SERVER_LS) target_link_libraries(${EXECUTABLE} web3jsonrpc) endif() if(READLINE_LS) diff --git a/eth/main.cpp b/eth/main.cpp index 447729c1a..25ebe5cdc 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -28,7 +28,6 @@ #include #include #if ETH_JSONRPC -//#include #include #endif #include diff --git a/libqethereum/CMakeLists.txt b/libqethereum/CMakeLists.txt index ba7cd3b67..709f7f066 100644 --- a/libqethereum/CMakeLists.txt +++ b/libqethereum/CMakeLists.txt @@ -59,7 +59,7 @@ endif() include_directories(/) qt5_use_modules(${EXECUTABLE} Core Gui WebKit WebKitWidgets Widgets Network Quick Qml) -target_link_libraries(${EXECUTABLE} ethereum secp256k1 ${CRYPTOPP_LS} ${JSONRPC_LS}) +target_link_libraries(${EXECUTABLE} ethereum secp256k1 ${CRYPTOPP_LS} ${JSONRPC_SERVER_LS}) if (APPLE) if (${ADDFRAMEWORKS}) diff --git a/libqethereum/QEthereum.h b/libqethereum/QEthereum.h index b4c17fdab..eeb5a493b 100644 --- a/libqethereum/QEthereum.h +++ b/libqethereum/QEthereum.h @@ -26,7 +26,6 @@ #include #include #include -//#include class QWebThree: public QObject { diff --git a/libweb3jsonrpc/CMakeLists.txt b/libweb3jsonrpc/CMakeLists.txt index 6966cd10a..ec8adbffb 100644 --- a/libweb3jsonrpc/CMakeLists.txt +++ b/libweb3jsonrpc/CMakeLists.txt @@ -24,8 +24,8 @@ endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) target_link_libraries(${EXECUTABLE} ${JSONCPP_LS}) -target_link_libraries(${EXECUTABLE} ${JSONRPC_LS}) target_link_libraries(${EXECUTABLE} ${JSONRPC_COMMON_LS}) +target_link_libraries(${EXECUTABLE} ${JSONRPC_SERVER_LS}) target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) if(READLINE_LS) target_link_libraries(${EXECUTABLE} ${READLINE_LS}) diff --git a/libweb3jsonrpc/CorsHttpServer.h b/libweb3jsonrpc/CorsHttpServer.h index 5dd3130a4..e697ecaa1 100644 --- a/libweb3jsonrpc/CorsHttpServer.h +++ b/libweb3jsonrpc/CorsHttpServer.h @@ -20,7 +20,6 @@ */ #include -//#include namespace jsonrpc { diff --git a/libweb3jsonrpc/WebThreeStubServer.h b/libweb3jsonrpc/WebThreeStubServer.h index 193f1f6ff..5a1f04d8e 100644 --- a/libweb3jsonrpc/WebThreeStubServer.h +++ b/libweb3jsonrpc/WebThreeStubServer.h @@ -29,7 +29,6 @@ #pragma warning(pop) #include -//#include #include #include #pragma GCC diagnostic push diff --git a/neth/CMakeLists.txt b/neth/CMakeLists.txt index ac275f663..d8b3d8f75 100644 --- a/neth/CMakeLists.txt +++ b/neth/CMakeLists.txt @@ -18,7 +18,7 @@ target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) -if(JSONRPC_LS) +if(JSONRPC_SERVER_LS) target_link_libraries(${EXECUTABLE} web3jsonrpc) endif() diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 63094fa23..52a73f84a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -16,7 +16,7 @@ target_link_libraries(testeth gmp) target_link_libraries(testeth solidity) target_link_libraries(testeth ${CRYPTOPP_LS}) target_link_libraries(testeth webthree) -if(JSONRPC_LS) +if(JSONRPC_SERVER_LS) target_link_libraries(testeth web3jsonrpc) target_link_libraries(testeth ${JSONRPC_CLIENT_LS}) endif() diff --git a/test/jsonrpc.cpp b/test/jsonrpc.cpp index f261a5164..1eee21357 100644 --- a/test/jsonrpc.cpp +++ b/test/jsonrpc.cpp @@ -31,8 +31,6 @@ #include #include #include -//#include -//#include #include #include "JsonSpiritHeaders.h" #include "TestHelper.h" From 874abf6e0b16f892f11d93b4ea2f595ced11623f Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 4 Nov 2014 12:03:24 +0100 Subject: [PATCH 008/277] fixed WebThreeStubServer constructor --- alethzero/MainWin.cpp | 2 +- eth/main.cpp | 9 ++++++--- libweb3jsonrpc/WebThreeStubServer.cpp | 4 ++-- libweb3jsonrpc/WebThreeStubServer.h | 2 +- neth/main.cpp | 7 +++++-- test/jsonrpc.cpp | 4 +++- third/MainWin.cpp | 2 +- 7 files changed, 19 insertions(+), 11 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index f413532b7..46d09f8c1 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -149,7 +149,7 @@ Main::Main(QWidget *parent) : m_webThree.reset(new WebThreeDirect(string("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir() + "/AlethZero", false, {"eth", "shh"})); - m_server = unique_ptr(new WebThreeStubServer(&m_qwebConnector, *web3(), keysAsVector(m_myKeys))); + m_server = unique_ptr(new WebThreeStubServer(m_qwebConnector, *web3(), keysAsVector(m_myKeys))); m_server->setIdentities(keysAsVector(owned())); m_server->StartListening(); diff --git a/eth/main.cpp b/eth/main.cpp index 25ebe5cdc..fb9e7e4a0 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -336,10 +336,12 @@ int main(int argc, char** argv) web3.connect(remoteHost, remotePort); #if ETH_JSONRPC - auto_ptr jsonrpcServer; + unique_ptr jsonrpcServer; + unique_ptr jsonrpcConnector; if (jsonrpc > -1) { - jsonrpcServer = auto_ptr(new WebThreeStubServer(new jsonrpc::CorsHttpServer(jsonrpc), web3, {us})); + jsonrpcConnector = unique_ptr(new jsonrpc::CorsHttpServer(jsonrpc)); + jsonrpcServer = unique_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, {us})); jsonrpcServer->setIdentities({us}); jsonrpcServer->StartListening(); } @@ -427,7 +429,8 @@ int main(int argc, char** argv) { if (jsonrpc < 0) jsonrpc = 8080; - jsonrpcServer = auto_ptr(new WebThreeStubServer(new jsonrpc::CorsHttpServer(jsonrpc), web3, {us})); + jsonrpcConnector = unique_ptr(new jsonrpc::CorsHttpServer(jsonrpc)); + jsonrpcServer = auto_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, {us})); jsonrpcServer->setIdentities({us}); jsonrpcServer->StartListening(); } diff --git a/libweb3jsonrpc/WebThreeStubServer.cpp b/libweb3jsonrpc/WebThreeStubServer.cpp index ed5907f53..aacc64a4e 100644 --- a/libweb3jsonrpc/WebThreeStubServer.cpp +++ b/libweb3jsonrpc/WebThreeStubServer.cpp @@ -216,8 +216,8 @@ static Json::Value toJson(h256 const& _h, shh::Envelope const& _e, shh::Message } -WebThreeStubServer::WebThreeStubServer(jsonrpc::AbstractServerConnector* _conn, WebThreeDirect& _web3, std::vector const& _accounts): - AbstractWebThreeStubServer(*_conn), +WebThreeStubServer::WebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, WebThreeDirect& _web3, std::vector const& _accounts): + AbstractWebThreeStubServer(_conn), m_web3(_web3) { setAccounts(_accounts); diff --git a/libweb3jsonrpc/WebThreeStubServer.h b/libweb3jsonrpc/WebThreeStubServer.h index 5a1f04d8e..f6b5cb224 100644 --- a/libweb3jsonrpc/WebThreeStubServer.h +++ b/libweb3jsonrpc/WebThreeStubServer.h @@ -60,7 +60,7 @@ class Interface; class WebThreeStubServer: public AbstractWebThreeStubServer { public: - WebThreeStubServer(jsonrpc::AbstractServerConnector* _conn, dev::WebThreeDirect& _web3, std::vector const& _accounts); + WebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, dev::WebThreeDirect& _web3, std::vector const& _accounts); virtual std::string account(); virtual Json::Value accounts(); diff --git a/neth/main.cpp b/neth/main.cpp index 8512cf77b..b2b9a155f 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -476,9 +476,11 @@ int main(int argc, char** argv) #if ETH_JSONRPC auto_ptr jsonrpcServer; + unique_ptr jsonrpcConnector; if (jsonrpc > -1) { - jsonrpcServer = auto_ptr(new WebThreeStubServer(new jsonrpc::HttpServer(jsonrpc), web3, {us})); + jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc)); + jsonrpcServer = auto_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, {us})); jsonrpcServer->setIdentities({us}); jsonrpcServer->StartListening(); } @@ -552,7 +554,8 @@ int main(int argc, char** argv) { if (jsonrpc < 0) jsonrpc = 8080; - jsonrpcServer = auto_ptr(new WebThreeStubServer(new jsonrpc::HttpServer(jsonrpc), web3, {us})); + jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc)); + jsonrpcServer = auto_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, {us})); jsonrpcServer->setIdentities({us}); jsonrpcServer->StartListening(); } diff --git a/test/jsonrpc.cpp b/test/jsonrpc.cpp index 1eee21357..80c4f5018 100644 --- a/test/jsonrpc.cpp +++ b/test/jsonrpc.cpp @@ -54,6 +54,7 @@ dev::WebThreeDirect web3(name, dbPath, true, s, np); unique_ptr jsonrpcServer; unique_ptr jsonrpcClient; +unique_ptr jsonrpcConnector; jsonrpc::HttpClient httpClient("http://localhost:8080"); struct JsonrpcFixture { @@ -63,7 +64,8 @@ struct JsonrpcFixture { web3.setIdealPeerCount(5); web3.ethereum()->setForceMining(true); - jsonrpcServer = unique_ptr(new WebThreeStubServer(new jsonrpc::CorsHttpServer(8080), web3, {})); + jsonrpcConnector = unique_ptr(new jsonrpc::CorsHttpServer(8080)); + jsonrpcServer = unique_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, {})); jsonrpcServer->setIdentities({}); jsonrpcServer->StartListening(); diff --git a/third/MainWin.cpp b/third/MainWin.cpp index c2dcb7ce2..7be9d8db3 100644 --- a/third/MainWin.cpp +++ b/third/MainWin.cpp @@ -117,7 +117,7 @@ Main::Main(QWidget *parent) : m_web3.reset(new WebThreeDirect("Third", getDataDir() + "/Third", false, {"eth", "shh"})); m_web3->connect(Host::pocHost()); - m_server = unique_ptr(new WebThreeStubServer(&m_qwebConnector, *web3(), keysAsVector(m_myKeys))); + m_server = unique_ptr(new WebThreeStubServer(m_qwebConnector, *web3(), keysAsVector(m_myKeys))); m_server->setIdentities(keysAsVector(owned())); m_server->StartListening(); From 851bae4dd56244d1fb7cd0b8575a47293cb5e76d Mon Sep 17 00:00:00 2001 From: sveneh Date: Tue, 4 Nov 2014 17:03:12 +0100 Subject: [PATCH 009/277] Test to bring in dependencies via CMake ExternalProject. Testing for libcryptopp only --- cmake/EthDependenciesDeprecated.cmake | 39 +++++++++++++-------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/cmake/EthDependenciesDeprecated.cmake b/cmake/EthDependenciesDeprecated.cmake index d1c51f6c4..06e3285c4 100644 --- a/cmake/EthDependenciesDeprecated.cmake +++ b/cmake/EthDependenciesDeprecated.cmake @@ -3,6 +3,19 @@ # deprecated. TODO will rewrite to proper CMake packages +include(ExternalProject) + +ExternalProject_Add(project_cryptopp + URL http://www.cryptopp.com/cryptopp562.zip + BINARY_DIR project_cryptopp-prefix/src/project_cryptopp + CONFIGURE_COMMAND "" + BUILD_COMMAND make -j 3 + INSTALL_COMMAND "" +) + + + + if("${TARGET_PLATFORM}" STREQUAL "w64") # set(MINIUPNPC_LS /usr/x86_64-w64-mingw32/lib/libminiupnpc.a) @@ -11,24 +24,9 @@ if("${TARGET_PLATFORM}" STREQUAL "w64") set(CRYPTOPP_ID /usr/x86_64-w64-mingw32/include/cryptopp) else() # Look for available Crypto++ version and if it is >= 5.6.2 - find_path(ID cryptlib.h - ../cryptopp/src - ../../cryptopp/src - /usr/include/cryptopp - /usr/include/crypto++ - /usr/local/include/cryptopp - /usr/local/include/crypto++ - /opt/local/include/cryptopp - /opt/local/include/crypto++ - ) - find_library(LS NAMES cryptoppeth cryptopp - ../cryptopp/src/../target/build/release - ../../cryptopp/src/../target/build/release - PATHS - /usr/lib - /usr/local/lib - /opt/local/lib - ) + + set(CRYPTOPP_ID ${CMAKE_CURRENT_BINARY_DIR}/project_cryptopp-prefix/src/project_cryptopp) + set(CRYPTOPP_LS cryptopp) if (ID AND LS) message(STATUS "Found Crypto++: ${ID}, ${LS}") @@ -180,9 +178,8 @@ else() set(QTQML 1) endif() -if(CRYPTOPP_ID) - include_directories(${CRYPTOPP_ID}) -endif() +include_directories(${CRYPTOPP_ID}) + if(PYTHON_ID) include_directories(${PYTHON_ID}) endif() From e33517a47d1b417df036cd5650d53b68181126f4 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 4 Nov 2014 19:45:33 +0100 Subject: [PATCH 010/277] cryptopp as external project --- cmake/EthDependenciesDeprecated.cmake | 15 ++++++--------- libdevcrypto/CMakeLists.txt | 1 + 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/cmake/EthDependenciesDeprecated.cmake b/cmake/EthDependenciesDeprecated.cmake index 06e3285c4..a87553dc1 100644 --- a/cmake/EthDependenciesDeprecated.cmake +++ b/cmake/EthDependenciesDeprecated.cmake @@ -6,17 +6,13 @@ include(ExternalProject) ExternalProject_Add(project_cryptopp - URL http://www.cryptopp.com/cryptopp562.zip - BINARY_DIR project_cryptopp-prefix/src/project_cryptopp - CONFIGURE_COMMAND "" - BUILD_COMMAND make -j 3 - INSTALL_COMMAND "" + URL http://www.cryptopp.com/cryptopp562.zip + BINARY_DIR project_cryptopp-prefix/src/project_cryptopp + CONFIGURE_COMMAND "" + BUILD_COMMAND make -j 3 + INSTALL_COMMAND "" ) - - - - if("${TARGET_PLATFORM}" STREQUAL "w64") # set(MINIUPNPC_LS /usr/x86_64-w64-mingw32/lib/libminiupnpc.a) set(LEVELDB_LS leveldb) @@ -27,6 +23,7 @@ else() set(CRYPTOPP_ID ${CMAKE_CURRENT_BINARY_DIR}/project_cryptopp-prefix/src/project_cryptopp) set(CRYPTOPP_LS cryptopp) + link_directories(${CMAKE_CURRENT_BINARY_DIR}/project_cryptopp-prefix/src/project_cryptopp) if (ID AND LS) message(STATUS "Found Crypto++: ${ID}, ${LS}") diff --git a/libdevcrypto/CMakeLists.txt b/libdevcrypto/CMakeLists.txt index e7f112f95..d9b0c96c9 100644 --- a/libdevcrypto/CMakeLists.txt +++ b/libdevcrypto/CMakeLists.txt @@ -15,6 +15,7 @@ file(GLOB HEADERS "*.h") include_directories(..) +add_dependencies(${EXECUTABLE} project_cryptopp) target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} secp256k1) target_link_libraries(${EXECUTABLE} gmp) From cb82c778519856ae51aa433c40d4c04577f4cded Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 5 Nov 2014 12:07:44 +0100 Subject: [PATCH 011/277] extdep dir --- extdep/CMakeLists.txt | 3 +++ extdep/cryptopp.cmake | 11 +++++++++++ 2 files changed, 14 insertions(+) create mode 100644 extdep/CMakeLists.txt create mode 100644 extdep/cryptopp.cmake diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt new file mode 100644 index 000000000..8ee232835 --- /dev/null +++ b/extdep/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.0) + +include(cryptopp.cmake) diff --git a/extdep/cryptopp.cmake b/extdep/cryptopp.cmake new file mode 100644 index 000000000..4e4ee85d7 --- /dev/null +++ b/extdep/cryptopp.cmake @@ -0,0 +1,11 @@ +include(ExternalProject) + +ExternalProject_Add(cryptopp + URL http://www.cryptopp.com/cryptopp562.zip + BINARY_DIR cryptopp-prefix/src/cryptopp + CONFIGURE_COMMAND "" + BUILD_COMMAND make -j 3 + INSTALL_COMMAND "" + ) + + From e88f8e72ed5cd5273452dd96272a711a9dbb2641 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 5 Nov 2014 12:14:49 +0100 Subject: [PATCH 012/277] miniupnpc cmake --- extdep/CMakeLists.txt | 2 ++ extdep/miniupnpc.cmake | 11 +++++++++++ 2 files changed, 13 insertions(+) create mode 100644 extdep/miniupnpc.cmake diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index 8ee232835..bcf906661 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -1,3 +1,5 @@ cmake_minimum_required(VERSION 3.0) include(cryptopp.cmake) +include(miniupnpc.cmake) + diff --git a/extdep/miniupnpc.cmake b/extdep/miniupnpc.cmake new file mode 100644 index 000000000..ae79f6369 --- /dev/null +++ b/extdep/miniupnpc.cmake @@ -0,0 +1,11 @@ +include(ExternalProject) + +ExternalProject_Add(miniupnpc + URL http://miniupnp.tuxfamily.org/files/download.php?file=miniupnpc-1.9.20141027.tar.gz + BINARY_DIR miniupnpc-prefix/src/miniupnpc + CONFIGURE_COMMAND "" + BUILD_COMMAND make -j 3 + INSTALL_COMMAND "" + ) + + From e5186e5c546ba60ed5803dcf2cbed4fe938069f5 Mon Sep 17 00:00:00 2001 From: sveneh Date: Thu, 6 Nov 2014 10:33:13 +0100 Subject: [PATCH 013/277] Initial change to support external dependency management via cmake. Proof of work, just for crypto++ dependency. Not yet functional. --- cmake/FindCryptoPP.cmake | 107 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 cmake/FindCryptoPP.cmake diff --git a/cmake/FindCryptoPP.cmake b/cmake/FindCryptoPP.cmake new file mode 100644 index 000000000..8fc743075 --- /dev/null +++ b/cmake/FindCryptoPP.cmake @@ -0,0 +1,107 @@ +# Module for locating the CryptoPP encryption library. +# +# Cutomizable variables: +# CRYPTOPP_ROOT_DIR +# This variable points to the CryptoPP root directory. On Windows the +# library location typically will have to be provided explicitly using the +# -D command-line option. The directory should include the include/cryptopp, +# lib and/or bin sub-directories. +# +# Read-Only variables: +# CRYPTOPP_FOUND +# Indicates that the library has been found. +# +# CRYPTOPP_INCLUDE_DIR +# Points to the CryptoPP include directory. +# +# CRYPTOPP_LIBRARIES +# Points to the CryptoPP libraries that should be passed to +# target_link_libararies. +# +# Copyright (c) 2010-2011 Sergiu Dotenco +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +INCLUDE (FindPackageHandleStandardArgs) + +SET (_CRYPTOPP_POSSIBLE_DIRS ${CRYPTOPP_ROOT_DIR}) +SET (_CRYPTOPP_POSSIBLE_INCLUDE_SUFFIXES include) +SET (_CRYPTOPP_POSSIBLE_LIB_SUFFIXES /lib /lib64) + +FIND_PATH (CRYPTOPP_ROOT_DIR + NAMES include/cryptopp/cryptlib.h + PATHS ${_CRYPTOPP_POSSIBLE_DIRS} + DOC "CryptoPP root directory") + +# Re-use the previous path: +FIND_PATH (CRYPTOPP_INCLUDE_DIR + NAMES cryptopp/cryptlib.h + PATHS ${CRYPTOPP_ROOT_DIR} + PATH_SUFFIXES ${_CRYPTOPP_POSSIBLE_INCLUDE_SUFFIXES} + DOC "CryptoPP include directory") + + FIND_LIBRARY (CRYPTOPP_LIBRARIES + NAMES cryptlib cryptopp libcryptopp + PATHS /usr/lib + PATH_SUFFIXES "" lib64) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS (CryptoPP DEFAULT_MSG CRYPTOPP_INCLUDE_DIR + CRYPTOPP_LIBRARIES) + +IF (CRYPTOPP_FOUND) + FILE (STRINGS ${CRYPTOPP_INCLUDE_DIR}/cryptopp/config.h + _CRYPTOPP_VERSION_TMP REGEX "^#define CRYPTOPP_VERSION[ \t]+[0-9]+$") + + STRING (REGEX REPLACE + "^#define CRYPTOPP_VERSION[ \t]+([0-9]+)" "\\1" _CRYPTOPP_VERSION_TMP + ${_CRYPTOPP_VERSION_TMP}) + + STRING (REGEX REPLACE "([0-9]+)[0-9][0-9]" "\\1" CRYPTOPP_VERSION_MAJOR + ${_CRYPTOPP_VERSION_TMP}) + STRING (REGEX REPLACE "[0-9]([0-9])[0-9]" "\\1" CRYPTOPP_VERSION_MINOR + ${_CRYPTOPP_VERSION_TMP}) + STRING (REGEX REPLACE "[0-9][0-9]([0-9])" "\\1" CRYPTOPP_VERSION_PATCH + ${_CRYPTOPP_VERSION_TMP}) + + SET (CRYPTOPP_VERSION_COUNT 3) + SET (CRYPTOPP_VERSION + ${CRYPTOPP_VERSION_MAJOR}.${CRYPTOPP_VERSION_MINOR}.${CRYPTOPP_VERSION_PATCH}) +ENDIF (CRYPTOPP_FOUND) + +IF (CRYPTOPP_FOUND) + IF (NOT CRYPTOPP_CACHED) + IF (NOT PACKAGE_FIND_QUIETLY) + MESSAGE (STATUS "CryptoPP version: ${CRYPTOPP_VERSION}") + ENDIF (NOT PACKAGE_FIND_QUIETLY) + + SET (CRYPTOPP_CACHED TRUE CACHE INTERNAL "" FORCE) + ENDIF (NOT CRYPTOPP_CACHED) +ELSE (CRYPTOPP_FOUND) + SET (CRYPTOPP_CACHED FALSE CACHE INTERNAL "" FORCE) + + IF (NOT PACKAGE_FIND_QUIETLY) + IF (PACKAGE_FIND_REQUIRED) + MESSAGE (FATAL_ERROR + "CryptoPP required but some files were not found. " + "Specify the CryptPP location using CRYPTOPP_ROOT_DIR") + ENDIF (PACKAGE_FIND_REQUIRED) + ENDIF (NOT PACKAGE_FIND_QUIETLY) +ENDIF (CRYPTOPP_FOUND) + +MARK_AS_ADVANCED (CRYPTOPP_INCLUDE_DIR CRYPTOPP_LIBRARIES) From 26d57961b4daa9b3f6cf27010f87970d80739fd9 Mon Sep 17 00:00:00 2001 From: sveneh Date: Thu, 6 Nov 2014 10:41:37 +0100 Subject: [PATCH 014/277] ... addition to last commit, these were lost. --- .gitignore | 2 + CMakeLists.txt | 24 +++--- cmake/EthDependenciesDeprecated.cmake | 35 --------- cmake/FindCryptoPP.cmake | 109 +++++++++++++------------- extdep/CMakeLists.txt | 10 ++- extdep/cryptopp.cmake | 12 +-- libdevcrypto/CMakeLists.txt | 6 +- libdevcrypto/CryptoPP.h | 24 +++--- libdevcrypto/EC.cpp | 4 +- libethcore/CMakeLists.txt | 2 +- test/CMakeLists.txt | 4 +- 11 files changed, 106 insertions(+), 126 deletions(-) diff --git a/.gitignore b/.gitignore index b38a3f1e3..ca18feb5b 100644 --- a/.gitignore +++ b/.gitignore @@ -29,7 +29,9 @@ build_xc *.user.* *~ +# build system build.*/ +extdep/install *.pyc diff --git a/CMakeLists.txt b/CMakeLists.txt index b4aa2352f..8d2ea151f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,17 @@ function(configureProject) endfunction() +# all dependencies that are not directly included in the cpp-ethereum distribution are defined here +# for this to work, download the dependency via the cmake script in extdep or install them manually! +function(checkExternalDependencies) + set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install") + + set (CRYPTOPP_ROOT_DIR ${ETH_DEPENDENCY_INSTALL_DIR}) + find_package (CryptoPP 5.6.2 REQUIRED) +endfunction() + + + function(createBuildInfo) # Set build platform; to be written to BuildInfo.h if (CMAKE_COMPILER_IS_MINGW) @@ -66,6 +77,8 @@ function(createBuildInfo) set(SRC_LIST BuildInfo.h) endfunction() + + ###################################################################################################### @@ -88,19 +101,12 @@ if ("${TARGET_PLATFORM}" STREQUAL "linux") set(CMAKE_THREAD_LIBS_INIT pthread) endif () -# Set default build type to Release w/debug info -# if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) -# set(CMAKE_BUILD_TYPE RelWithDebInfo) -# endif() - - include(EthCompilerSettings) message("-- CXXFLAGS: ${CMAKE_CXX_FLAGS}") -#add_definitions("-DETH_BUILD_TYPE=${ETH_BUILD_TYPE}") -#add_definitions("-DETH_BUILD_PLATFORM=${ETH_BUILD_PLATFORM}") - +checkExternalDependencies() +# TODO this will go away soon! include(EthDependenciesDeprecated) createBuildInfo() diff --git a/cmake/EthDependenciesDeprecated.cmake b/cmake/EthDependenciesDeprecated.cmake index a87553dc1..87a981fc9 100644 --- a/cmake/EthDependenciesDeprecated.cmake +++ b/cmake/EthDependenciesDeprecated.cmake @@ -3,45 +3,10 @@ # deprecated. TODO will rewrite to proper CMake packages -include(ExternalProject) - -ExternalProject_Add(project_cryptopp - URL http://www.cryptopp.com/cryptopp562.zip - BINARY_DIR project_cryptopp-prefix/src/project_cryptopp - CONFIGURE_COMMAND "" - BUILD_COMMAND make -j 3 - INSTALL_COMMAND "" -) - if("${TARGET_PLATFORM}" STREQUAL "w64") # set(MINIUPNPC_LS /usr/x86_64-w64-mingw32/lib/libminiupnpc.a) set(LEVELDB_LS leveldb) - set(CRYPTOPP_LS cryptopp) - set(CRYPTOPP_ID /usr/x86_64-w64-mingw32/include/cryptopp) else() - # Look for available Crypto++ version and if it is >= 5.6.2 - - set(CRYPTOPP_ID ${CMAKE_CURRENT_BINARY_DIR}/project_cryptopp-prefix/src/project_cryptopp) - set(CRYPTOPP_LS cryptopp) - link_directories(${CMAKE_CURRENT_BINARY_DIR}/project_cryptopp-prefix/src/project_cryptopp) - - if (ID AND LS) - message(STATUS "Found Crypto++: ${ID}, ${LS}") - set(_CRYPTOPP_VERSION_HEADER ${ID}/config.h) - if(EXISTS ${_CRYPTOPP_VERSION_HEADER}) - file(STRINGS ${_CRYPTOPP_VERSION_HEADER} _CRYPTOPP_VERSION REGEX "^#define CRYPTOPP_VERSION[ \t]+[0-9]+$") - string(REGEX REPLACE "^#define CRYPTOPP_VERSION[ \t]+([0-9]+)" "\\1" _CRYPTOPP_VERSION ${_CRYPTOPP_VERSION}) - if(${_CRYPTOPP_VERSION} LESS 562) - message(FATAL_ERROR "Crypto++ version found is smaller than 5.6.2.") - else() - set(CRYPTOPP_ID ${ID} CACHE FILEPATH "") - set(CRYPTOPP_LS ${LS} CACHE FILEPATH "") - message(STATUS "Crypto++ found and version greater or equal to 5.6.2") - endif() - endif() - else() - message(STATUS "Crypto++ Not Found: ${CRYPTOPP_ID}, ${CRYPTOPP_LS}") - endif() find_path( LEVELDB_ID leveldb/db.h /usr/include diff --git a/cmake/FindCryptoPP.cmake b/cmake/FindCryptoPP.cmake index 8fc743075..74a01e83a 100644 --- a/cmake/FindCryptoPP.cmake +++ b/cmake/FindCryptoPP.cmake @@ -1,24 +1,25 @@ -# Module for locating the CryptoPP encryption library. +# Module for locating the Crypto++ encryption library. # -# Cutomizable variables: +# Customizable variables: # CRYPTOPP_ROOT_DIR # This variable points to the CryptoPP root directory. On Windows the # library location typically will have to be provided explicitly using the # -D command-line option. The directory should include the include/cryptopp, # lib and/or bin sub-directories. # -# Read-Only variables: +# Read-only variables: # CRYPTOPP_FOUND -# Indicates that the library has been found. +# Indicates whether the library has been found. # -# CRYPTOPP_INCLUDE_DIR +# CRYPTOPP_INCLUDE_DIRS # Points to the CryptoPP include directory. # # CRYPTOPP_LIBRARIES # Points to the CryptoPP libraries that should be passed to # target_link_libararies. # -# Copyright (c) 2010-2011 Sergiu Dotenco +# +# Copyright (c) 2012 Sergiu Dotenco # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -40,68 +41,68 @@ INCLUDE (FindPackageHandleStandardArgs) -SET (_CRYPTOPP_POSSIBLE_DIRS ${CRYPTOPP_ROOT_DIR}) -SET (_CRYPTOPP_POSSIBLE_INCLUDE_SUFFIXES include) -SET (_CRYPTOPP_POSSIBLE_LIB_SUFFIXES /lib /lib64) - FIND_PATH (CRYPTOPP_ROOT_DIR - NAMES include/cryptopp/cryptlib.h - PATHS ${_CRYPTOPP_POSSIBLE_DIRS} + NAMES cryptopp/cryptlib.h include/cryptopp/cryptlib.h + PATHS ENV CRYPTOPPROOT DOC "CryptoPP root directory") # Re-use the previous path: FIND_PATH (CRYPTOPP_INCLUDE_DIR NAMES cryptopp/cryptlib.h - PATHS ${CRYPTOPP_ROOT_DIR} - PATH_SUFFIXES ${_CRYPTOPP_POSSIBLE_INCLUDE_SUFFIXES} + HINTS ${CRYPTOPP_ROOT_DIR} + PATH_SUFFIXES include DOC "CryptoPP include directory") - FIND_LIBRARY (CRYPTOPP_LIBRARIES - NAMES cryptlib cryptopp libcryptopp - PATHS /usr/lib - PATH_SUFFIXES "" lib64) +FIND_LIBRARY (CRYPTOPP_LIBRARY_DEBUG + NAMES cryptlibd cryptoppd + HINTS ${CRYPTOPP_ROOT_DIR} + PATH_SUFFIXES lib + DOC "CryptoPP debug library") + +FIND_LIBRARY (CRYPTOPP_LIBRARY_RELEASE + NAMES cryptlib cryptopp + HINTS ${CRYPTOPP_ROOT_DIR} + PATH_SUFFIXES lib + DOC "CryptoPP release library") -FIND_PACKAGE_HANDLE_STANDARD_ARGS (CryptoPP DEFAULT_MSG CRYPTOPP_INCLUDE_DIR - CRYPTOPP_LIBRARIES) +IF (CRYPTOPP_LIBRARY_DEBUG AND CRYPTOPP_LIBRARY_RELEASE) + SET (CRYPTOPP_LIBRARY + optimized ${CRYPTOPP_LIBRARY_RELEASE} + debug ${CRYPTOPP_LIBRARY_DEBUG} CACHE DOC "CryptoPP library") +ELSEIF (CRYPTOPP_LIBRARY_RELEASE) + SET (CRYPTOPP_LIBRARY ${CRYPTOPP_LIBRARY_RELEASE} CACHE DOC + "CryptoPP library") +ENDIF (CRYPTOPP_LIBRARY_DEBUG AND CRYPTOPP_LIBRARY_RELEASE) -IF (CRYPTOPP_FOUND) - FILE (STRINGS ${CRYPTOPP_INCLUDE_DIR}/cryptopp/config.h - _CRYPTOPP_VERSION_TMP REGEX "^#define CRYPTOPP_VERSION[ \t]+[0-9]+$") +IF (CRYPTOPP_INCLUDE_DIR) + SET (_CRYPTOPP_VERSION_HEADER ${CRYPTOPP_INCLUDE_DIR}/cryptopp/config.h) - STRING (REGEX REPLACE - "^#define CRYPTOPP_VERSION[ \t]+([0-9]+)" "\\1" _CRYPTOPP_VERSION_TMP - ${_CRYPTOPP_VERSION_TMP}) + IF (EXISTS ${_CRYPTOPP_VERSION_HEADER}) + FILE (STRINGS ${_CRYPTOPP_VERSION_HEADER} _CRYPTOPP_VERSION_TMP REGEX + "^#define CRYPTOPP_VERSION[ \t]+[0-9]+$") - STRING (REGEX REPLACE "([0-9]+)[0-9][0-9]" "\\1" CRYPTOPP_VERSION_MAJOR - ${_CRYPTOPP_VERSION_TMP}) - STRING (REGEX REPLACE "[0-9]([0-9])[0-9]" "\\1" CRYPTOPP_VERSION_MINOR - ${_CRYPTOPP_VERSION_TMP}) - STRING (REGEX REPLACE "[0-9][0-9]([0-9])" "\\1" CRYPTOPP_VERSION_PATCH - ${_CRYPTOPP_VERSION_TMP}) + STRING (REGEX REPLACE + "^#define CRYPTOPP_VERSION[ \t]+([0-9]+)" "\\1" _CRYPTOPP_VERSION_TMP + ${_CRYPTOPP_VERSION_TMP}) - SET (CRYPTOPP_VERSION_COUNT 3) - SET (CRYPTOPP_VERSION - ${CRYPTOPP_VERSION_MAJOR}.${CRYPTOPP_VERSION_MINOR}.${CRYPTOPP_VERSION_PATCH}) -ENDIF (CRYPTOPP_FOUND) + STRING (REGEX REPLACE "([0-9]+)[0-9][0-9]" "\\1" CRYPTOPP_VERSION_MAJOR + ${_CRYPTOPP_VERSION_TMP}) + STRING (REGEX REPLACE "[0-9]([0-9])[0-9]" "\\1" CRYPTOPP_VERSION_MINOR + ${_CRYPTOPP_VERSION_TMP}) + STRING (REGEX REPLACE "[0-9][0-9]([0-9])" "\\1" CRYPTOPP_VERSION_PATCH + ${_CRYPTOPP_VERSION_TMP}) -IF (CRYPTOPP_FOUND) - IF (NOT CRYPTOPP_CACHED) - IF (NOT PACKAGE_FIND_QUIETLY) - MESSAGE (STATUS "CryptoPP version: ${CRYPTOPP_VERSION}") - ENDIF (NOT PACKAGE_FIND_QUIETLY) + SET (CRYPTOPP_VERSION_COUNT 3) + SET (CRYPTOPP_VERSION + ${CRYPTOPP_VERSION_MAJOR}.${CRYPTOPP_VERSION_MINOR}.${CRYPTOPP_VERSION_PATCH}) + ENDIF (EXISTS ${_CRYPTOPP_VERSION_HEADER}) +ENDIF (CRYPTOPP_INCLUDE_DIR) - SET (CRYPTOPP_CACHED TRUE CACHE INTERNAL "" FORCE) - ENDIF (NOT CRYPTOPP_CACHED) -ELSE (CRYPTOPP_FOUND) - SET (CRYPTOPP_CACHED FALSE CACHE INTERNAL "" FORCE) +SET (CRYPTOPP_INCLUDE_DIRS ${CRYPTOPP_INCLUDE_DIR}) +SET (CRYPTOPP_LIBRARIES ${CRYPTOPP_LIBRARY}) - IF (NOT PACKAGE_FIND_QUIETLY) - IF (PACKAGE_FIND_REQUIRED) - MESSAGE (FATAL_ERROR - "CryptoPP required but some files were not found. " - "Specify the CryptPP location using CRYPTOPP_ROOT_DIR") - ENDIF (PACKAGE_FIND_REQUIRED) - ENDIF (NOT PACKAGE_FIND_QUIETLY) -ENDIF (CRYPTOPP_FOUND) +MARK_AS_ADVANCED (CRYPTOPP_INCLUDE_DIR CRYPTOPP_LIBRARY CRYPTOPP_LIBRARY_DEBUG + CRYPTOPP_LIBRARY_RELEASE) -MARK_AS_ADVANCED (CRYPTOPP_INCLUDE_DIR CRYPTOPP_LIBRARIES) +FIND_PACKAGE_HANDLE_STANDARD_ARGS (CryptoPP REQUIRED_VARS CRYPTOPP_ROOT_DIR + CRYPTOPP_INCLUDE_DIR CRYPTOPP_LIBRARY VERSION_VAR CRYPTOPP_VERSION) diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index bcf906661..abf3d6998 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -1,5 +1,11 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 2.8) + +include(ExternalProject) + +# dependencies will be installed into this directory +set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install") + include(cryptopp.cmake) -include(miniupnpc.cmake) +#include(miniupnpc.cmake) diff --git a/extdep/cryptopp.cmake b/extdep/cryptopp.cmake index 4e4ee85d7..e60a1fa5e 100644 --- a/extdep/cryptopp.cmake +++ b/extdep/cryptopp.cmake @@ -1,11 +1,11 @@ -include(ExternalProject) - -ExternalProject_Add(cryptopp - URL http://www.cryptopp.com/cryptopp562.zip +ExternalProject_Add( + cryptopp + URL https://github.com/mmoss/cryptopp/archive/v5.6.2.zip BINARY_DIR cryptopp-prefix/src/cryptopp CONFIGURE_COMMAND "" - BUILD_COMMAND make -j 3 + BUILD_COMMAND scons --shared --prefix=${ETH_DEPENDENCY_INSTALL_DIR} INSTALL_COMMAND "" - ) +) + diff --git a/libdevcrypto/CMakeLists.txt b/libdevcrypto/CMakeLists.txt index ed5e4416d..1dd709ffe 100644 --- a/libdevcrypto/CMakeLists.txt +++ b/libdevcrypto/CMakeLists.txt @@ -11,14 +11,14 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -include_directories(..) +include_directories(..) +include_directories(${CRYPTOPP_INCLUDE_DIR}) -add_dependencies(${EXECUTABLE} project_cryptopp) target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} secp256k1) target_link_libraries(${EXECUTABLE} gmp) target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) -target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) +target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) if("${TARGET_PLATFORM}" STREQUAL "w64") target_link_libraries(${EXECUTABLE} boost_system-mt-s) diff --git a/libdevcrypto/CryptoPP.h b/libdevcrypto/CryptoPP.h index 6070b651b..52a28df1a 100644 --- a/libdevcrypto/CryptoPP.h +++ b/libdevcrypto/CryptoPP.h @@ -33,18 +33,18 @@ #pragma GCC diagnostic ignored "-Wunused-variable" #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" #pragma GCC diagnostic ignored "-Wextra" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #pragma warning(pop) #pragma GCC diagnostic pop diff --git a/libdevcrypto/EC.cpp b/libdevcrypto/EC.cpp index 5086e3203..4edd6a648 100644 --- a/libdevcrypto/EC.cpp +++ b/libdevcrypto/EC.cpp @@ -14,7 +14,8 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file EC.cpp +/** + * @file EC.cpp * @author Alex Leverington * @date 2014 * @@ -29,7 +30,6 @@ #pragma GCC diagnostic ignored "-Wunused-variable" #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" #pragma GCC diagnostic ignored "-Wextra" -#include #pragma warning(pop) #pragma GCC diagnostic pop #include "CryptoPP.h" diff --git a/libethcore/CMakeLists.txt b/libethcore/CMakeLists.txt index f5cf00b57..49cfc1941 100644 --- a/libethcore/CMakeLists.txt +++ b/libethcore/CMakeLists.txt @@ -12,13 +12,13 @@ else() endif() include_directories(..) +include_directories(${CRYPTOPP_INCLUDE_DIR}) target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} secp256k1) target_link_libraries(${EXECUTABLE} gmp) target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) -target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) if("${TARGET_PLATFORM}" STREQUAL "w64") target_link_libraries(${EXECUTABLE} boost_system-mt-s) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a11c9fa16..f591e011b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -14,10 +14,10 @@ target_link_libraries(testeth ethcore) target_link_libraries(testeth secp256k1) target_link_libraries(testeth gmp) target_link_libraries(testeth solidity) -target_link_libraries(testeth ${CRYPTOPP_LS}) +target_link_libraries(testeth ${CRYPTOPP_LIBRARIES}) target_link_libraries(testeth webthree) if(JSONRPC_LS) -target_link_libraries(testeth web3jsonrpc) + target_link_libraries(testeth web3jsonrpc) endif() target_link_libraries(createRandomTest ethereum) From 130681763337bd552c87e1f0ed1ab205c8fed2da Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 6 Nov 2014 11:27:39 +0100 Subject: [PATCH 015/277] cryptopp compiling on macos --- extdep/CMakeLists.txt | 1 + extdep/cryptopp.cmake | 12 ++++++++++-- extdep/curl.cmake | 11 +++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 extdep/curl.cmake diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index abf3d6998..766053655 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -5,6 +5,7 @@ include(ExternalProject) # dependencies will be installed into this directory set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install") +file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}) include(cryptopp.cmake) #include(miniupnpc.cmake) diff --git a/extdep/cryptopp.cmake b/extdep/cryptopp.cmake index e60a1fa5e..a8e28b43e 100644 --- a/extdep/cryptopp.cmake +++ b/extdep/cryptopp.cmake @@ -1,3 +1,12 @@ +if(${APPLE}) +ExternalProject_Add(cryptopp + URL http://www.cryptopp.com/cryptopp562.zip + BINARY_DIR cryptopp-prefix/src/cryptopp + CONFIGURE_COMMAND "" + BUILD_COMMAND make -j 3 + INSTALL_COMMAND make dynamic install PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} + ) +else() ExternalProject_Add( cryptopp URL https://github.com/mmoss/cryptopp/archive/v5.6.2.zip @@ -6,6 +15,5 @@ ExternalProject_Add( BUILD_COMMAND scons --shared --prefix=${ETH_DEPENDENCY_INSTALL_DIR} INSTALL_COMMAND "" ) - - +endif() diff --git a/extdep/curl.cmake b/extdep/curl.cmake new file mode 100644 index 000000000..c98c98b9f --- /dev/null +++ b/extdep/curl.cmake @@ -0,0 +1,11 @@ +include(ExternalProject) + +ExternalProject_Add(curl + URL http://curl.haxx.se/download/curl-7.38.0.tar.bz2 + BINARY_DIR curl-prefix/src/curl + CONFIGURE_COMMAND ./configure --with-darwinssl + BUILD_COMMAND make -j 3 + INSTALL_COMMAND "" + ) + + From 33368e31642aa388ea89a0c372b29e603351a2c0 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 6 Nov 2014 11:49:40 +0100 Subject: [PATCH 016/277] curl properly building to build dir --- extdep/CMakeLists.txt | 1 + extdep/cryptopp.cmake | 3 +-- extdep/curl.cmake | 9 +++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index 766053655..c89457f01 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -8,5 +8,6 @@ set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install") file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}) include(cryptopp.cmake) +include(curl.cmake) #include(miniupnpc.cmake) diff --git a/extdep/cryptopp.cmake b/extdep/cryptopp.cmake index a8e28b43e..0f83d0115 100644 --- a/extdep/cryptopp.cmake +++ b/extdep/cryptopp.cmake @@ -7,8 +7,7 @@ ExternalProject_Add(cryptopp INSTALL_COMMAND make dynamic install PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} ) else() -ExternalProject_Add( - cryptopp +ExternalProject_Add(cryptopp URL https://github.com/mmoss/cryptopp/archive/v5.6.2.zip BINARY_DIR cryptopp-prefix/src/cryptopp CONFIGURE_COMMAND "" diff --git a/extdep/curl.cmake b/extdep/curl.cmake index c98c98b9f..5d915c79b 100644 --- a/extdep/curl.cmake +++ b/extdep/curl.cmake @@ -1,11 +1,12 @@ -include(ExternalProject) - +if(${APPLE}) ExternalProject_Add(curl URL http://curl.haxx.se/download/curl-7.38.0.tar.bz2 BINARY_DIR curl-prefix/src/curl - CONFIGURE_COMMAND ./configure --with-darwinssl + CONFIGURE_COMMAND ./configure --with-darwinssl --prefix=${ETH_DEPENDENCY_INSTALL_DIR} --exec-prefix=${ETH_DEPENDENCY_INSTALL_DIR} BUILD_COMMAND make -j 3 - INSTALL_COMMAND "" + INSTALL_COMMAND make install ) +else() +endif() From cec5c56ca640b1cb7470ca4eb68e40c56b5e20b0 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 6 Nov 2014 12:26:21 +0100 Subject: [PATCH 017/277] jsonrpc is building properly to intall folder --- extdep/CMakeLists.txt | 1 + extdep/FindCURL.cmake | 9 +++++++++ extdep/json-rpc-cpp.cmake | 11 +++++++++++ 3 files changed, 21 insertions(+) create mode 100644 extdep/FindCURL.cmake create mode 100644 extdep/json-rpc-cpp.cmake diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index c89457f01..f28ad1c8e 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -9,5 +9,6 @@ file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}) include(cryptopp.cmake) include(curl.cmake) +include(json-rpc-cpp.cmake) #include(miniupnpc.cmake) diff --git a/extdep/FindCURL.cmake b/extdep/FindCURL.cmake new file mode 100644 index 000000000..6a82ebb22 --- /dev/null +++ b/extdep/FindCURL.cmake @@ -0,0 +1,9 @@ +# hacky way to resolve nested dependencies +find_library(CURL_LIBRARY NAMES curl + PATHS + ${ETH_DEPENDENCY_INSTALL_DIR}/lib + ) + +set(CURL_LIBRARIES ${CURL_LIBRARY}) +set(CURL_INCLUDE_DIRS ${ETH_DEPENDENCY_INSTALL_DIR}/include) + diff --git a/extdep/json-rpc-cpp.cmake b/extdep/json-rpc-cpp.cmake new file mode 100644 index 000000000..28c5f7cf1 --- /dev/null +++ b/extdep/json-rpc-cpp.cmake @@ -0,0 +1,11 @@ +ExternalProject_Add(json-rpc-cpp + DEPENDS curl + GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git + GIT_TAG eaca2481e2889d5a5b748383fb02b1d395969cd4 + BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp + CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR} -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev . + BUILD_COMMAND make jsonrpc -j 3 + INSTALL_COMMAND make install + ) + + From ff174957112cdb4312b10711da28dd99f63ebac2 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 6 Nov 2014 12:41:43 +0100 Subject: [PATCH 018/277] miniupnpc mac build --- extdep/CMakeLists.txt | 2 +- extdep/miniupnpc.cmake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index f28ad1c8e..121f21067 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -10,5 +10,5 @@ file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}) include(cryptopp.cmake) include(curl.cmake) include(json-rpc-cpp.cmake) -#include(miniupnpc.cmake) +include(miniupnpc.cmake) diff --git a/extdep/miniupnpc.cmake b/extdep/miniupnpc.cmake index ae79f6369..b690ec2f2 100644 --- a/extdep/miniupnpc.cmake +++ b/extdep/miniupnpc.cmake @@ -5,7 +5,7 @@ ExternalProject_Add(miniupnpc BINARY_DIR miniupnpc-prefix/src/miniupnpc CONFIGURE_COMMAND "" BUILD_COMMAND make -j 3 - INSTALL_COMMAND "" + INSTALL_COMMAND make install INSTALLPREFIX=${ETH_DEPENDENCY_INSTALL_DIR} ) From c29321d01cee6c4c5495930822fd15c4fd6a2fe0 Mon Sep 17 00:00:00 2001 From: sveneh Date: Thu, 6 Nov 2014 15:56:00 +0100 Subject: [PATCH 019/277] full project compile with crypto++ dependency --- CMakeLists.txt | 15 ++++----------- alethzero/CMakeLists.txt | 2 +- cmake/EthDependencies.cmake | 11 +++++++++++ cmake/EthDependenciesDeprecated.cmake | 2 -- eth/CMakeLists.txt | 1 - exp/CMakeLists.txt | 1 - iethxi/CMakeLists.txt | 2 +- libdevcore/CMakeLists.txt | 1 - libethereum/CMakeLists.txt | 1 - libevm/CMakeLists.txt | 1 - libp2p/CMakeLists.txt | 1 - libqethereum/CMakeLists.txt | 2 +- libwebthree/CMakeLists.txt | 1 - libwhisper/CMakeLists.txt | 1 - neth/CMakeLists.txt | 1 - test/CMakeLists.txt | 8 +++++++- third/CMakeLists.txt | 2 +- walleth/CMakeLists.txt | 2 +- 18 files changed, 27 insertions(+), 28 deletions(-) create mode 100644 cmake/EthDependencies.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d2ea151f..f3de28909 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,16 +42,6 @@ function(configureProject) endfunction() -# all dependencies that are not directly included in the cpp-ethereum distribution are defined here -# for this to work, download the dependency via the cmake script in extdep or install them manually! -function(checkExternalDependencies) - set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install") - - set (CRYPTOPP_ROOT_DIR ${ETH_DEPENDENCY_INSTALL_DIR}) - find_package (CryptoPP 5.6.2 REQUIRED) -endfunction() - - function(createBuildInfo) # Set build platform; to be written to BuildInfo.h @@ -104,7 +94,10 @@ endif () include(EthCompilerSettings) message("-- CXXFLAGS: ${CMAKE_CXX_FLAGS}") -checkExternalDependencies() + +# this must be an include, as a function it would messs up with variable scope! +include(EthDependencies) + # TODO this will go away soon! include(EthDependenciesDeprecated) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index 1548abbe3..034b0dce9 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -53,7 +53,7 @@ else () endif () qt5_use_modules(${EXECUTEABLE} Core)# Gui Widgets Network WebKit WebKitWidgets) -target_link_libraries(${EXECUTEABLE} webthree qethereum ethereum evm ethcore devcrypto secp256k1 gmp ${CRYPTOPP_LS} serpent lll evmface devcore web3jsonrpc jsqrc) +target_link_libraries(${EXECUTEABLE} webthree qethereum ethereum evm ethcore devcrypto secp256k1 gmp serpent lll evmface devcore web3jsonrpc jsqrc) if (APPLE) # First have qt5 install plugins and frameworks diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake new file mode 100644 index 000000000..5934b1512 --- /dev/null +++ b/cmake/EthDependencies.cmake @@ -0,0 +1,11 @@ +# all dependencies that are not directly included in the cpp-ethereum distribution are defined here +# for this to work, download the dependency via the cmake script in extdep or install them manually! + +set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install") + +set (CRYPTOPP_ROOT_DIR ${ETH_DEPENDENCY_INSTALL_DIR}) +find_package (CryptoPP 5.6.2 REQUIRED) +message("-- CryptoPP header: ${CRYPTOPP_INCLUDE_DIRS}") +message("-- CryptoPP libs : ${CRYPTOPP_LIBRARIES}") + + diff --git a/cmake/EthDependenciesDeprecated.cmake b/cmake/EthDependenciesDeprecated.cmake index 87a981fc9..4be546a13 100644 --- a/cmake/EthDependenciesDeprecated.cmake +++ b/cmake/EthDependenciesDeprecated.cmake @@ -140,8 +140,6 @@ else() set(QTQML 1) endif() -include_directories(${CRYPTOPP_ID}) - if(PYTHON_ID) include_directories(${PYTHON_ID}) endif() diff --git a/eth/CMakeLists.txt b/eth/CMakeLists.txt index 7c997b256..793223abd 100644 --- a/eth/CMakeLists.txt +++ b/eth/CMakeLists.txt @@ -16,7 +16,6 @@ if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) -target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) if(JSONRPC_LS) target_link_libraries(${EXECUTABLE} web3jsonrpc) endif() diff --git a/exp/CMakeLists.txt b/exp/CMakeLists.txt index da6775798..89e5580a4 100644 --- a/exp/CMakeLists.txt +++ b/exp/CMakeLists.txt @@ -11,7 +11,6 @@ add_executable(${EXECUTABLE} ${SRC_LIST}) target_link_libraries(${EXECUTABLE} ethereum) target_link_libraries(${EXECUTABLE} p2p) target_link_libraries(${EXECUTABLE} gmp) -target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() diff --git a/iethxi/CMakeLists.txt b/iethxi/CMakeLists.txt index fc8edf1dc..77c26dd4d 100644 --- a/iethxi/CMakeLists.txt +++ b/iethxi/CMakeLists.txt @@ -59,7 +59,7 @@ else () endif () qt5_use_modules(${EXECUTEABLE} Core Gui Widgets Network Quick Qml) -target_link_libraries(${EXECUTEABLE} qethereum ethereum secp256k1 ${CRYPTOPP_LS}) +target_link_libraries(${EXECUTEABLE} qethereum ethereum secp256k1) if (APPLE) if (${ADDFRAMEWORKS}) diff --git a/libdevcore/CMakeLists.txt b/libdevcore/CMakeLists.txt index 7c54301c9..c3857a622 100644 --- a/libdevcore/CMakeLists.txt +++ b/libdevcore/CMakeLists.txt @@ -20,7 +20,6 @@ endif() include_directories(..) if("${TARGET_PLATFORM}" STREQUAL "w64") - include_directories(/usr/x86_64-w64-mingw32/include/cryptopp) target_link_libraries(${EXECUTABLE} boost_system-mt-s) target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) target_link_libraries(${EXECUTABLE} iphlpapi) diff --git a/libethereum/CMakeLists.txt b/libethereum/CMakeLists.txt index cb2049886..3c00ad6a7 100644 --- a/libethereum/CMakeLists.txt +++ b/libethereum/CMakeLists.txt @@ -26,7 +26,6 @@ if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) -target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) target_link_libraries(${EXECUTABLE} gmp) if("${TARGET_PLATFORM}" STREQUAL "w64") diff --git a/libevm/CMakeLists.txt b/libevm/CMakeLists.txt index 0c31a9fc3..0a1d8c3cd 100644 --- a/libevm/CMakeLists.txt +++ b/libevm/CMakeLists.txt @@ -25,7 +25,6 @@ if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) -target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) if("${TARGET_PLATFORM}" STREQUAL "w64") target_link_libraries(${EXECUTABLE} boost_system-mt-s) diff --git a/libp2p/CMakeLists.txt b/libp2p/CMakeLists.txt index 9e20fd99f..f0aeceae5 100644 --- a/libp2p/CMakeLists.txt +++ b/libp2p/CMakeLists.txt @@ -22,7 +22,6 @@ if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) -target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) target_link_libraries(${EXECUTABLE} gmp) if("${TARGET_PLATFORM}" STREQUAL "w64") diff --git a/libqethereum/CMakeLists.txt b/libqethereum/CMakeLists.txt index ba7cd3b67..d7e545ede 100644 --- a/libqethereum/CMakeLists.txt +++ b/libqethereum/CMakeLists.txt @@ -59,7 +59,7 @@ endif() include_directories(/) qt5_use_modules(${EXECUTABLE} Core Gui WebKit WebKitWidgets Widgets Network Quick Qml) -target_link_libraries(${EXECUTABLE} ethereum secp256k1 ${CRYPTOPP_LS} ${JSONRPC_LS}) +target_link_libraries(${EXECUTABLE} ethereum secp256k1 ${JSONRPC_LS}) if (APPLE) if (${ADDFRAMEWORKS}) diff --git a/libwebthree/CMakeLists.txt b/libwebthree/CMakeLists.txt index cc1b290f5..fbaa43b45 100644 --- a/libwebthree/CMakeLists.txt +++ b/libwebthree/CMakeLists.txt @@ -27,7 +27,6 @@ if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) -target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) target_link_libraries(${EXECUTABLE} gmp) if("${TARGET_PLATFORM}" STREQUAL "w64") diff --git a/libwhisper/CMakeLists.txt b/libwhisper/CMakeLists.txt index 364d9759a..fdf69650a 100644 --- a/libwhisper/CMakeLists.txt +++ b/libwhisper/CMakeLists.txt @@ -24,7 +24,6 @@ if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) -target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) target_link_libraries(${EXECUTABLE} gmp) if("${TARGET_PLATFORM}" STREQUAL "w64") diff --git a/neth/CMakeLists.txt b/neth/CMakeLists.txt index ac275f663..68044fe7c 100644 --- a/neth/CMakeLists.txt +++ b/neth/CMakeLists.txt @@ -17,7 +17,6 @@ if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) -target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) if(JSONRPC_LS) target_link_libraries(${EXECUTABLE} web3jsonrpc) endif() diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f591e011b..4f02f96bb 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -4,18 +4,23 @@ aux_source_directory(. SRC_LIST) list(REMOVE_ITEM SRC_LIST "./createRandomTest.cpp") include_directories(..) +include_directories(${CRYPTOPP_INCLUDE_DIR}) file(GLOB HEADERS "*.h") add_executable(testeth ${SRC_LIST} ${HEADERS}) add_executable(createRandomTest createRandomTest.cpp vm.cpp) + target_link_libraries(testeth ethereum) target_link_libraries(testeth ethcore) target_link_libraries(testeth secp256k1) target_link_libraries(testeth gmp) target_link_libraries(testeth solidity) -target_link_libraries(testeth ${CRYPTOPP_LIBRARIES}) target_link_libraries(testeth webthree) + +#TODO this on should not be necessary, it should have been brought in from ethcore dependency... +target_link_libraries(testeth ${CRYPTOPP_LIBRARIES}) + if(JSONRPC_LS) target_link_libraries(testeth web3jsonrpc) endif() @@ -24,6 +29,7 @@ target_link_libraries(createRandomTest ethereum) target_link_libraries(createRandomTest ethcore) target_link_libraries(createRandomTest boost_chrono) target_link_libraries(createRandomTest boost_unit_test_framework) +target_link_libraries(createRandomTest ${CRYPTOPP_LIBRARIES}) if ("${TARGET_PLATFORM}" STREQUAL "w64") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") diff --git a/third/CMakeLists.txt b/third/CMakeLists.txt index 6edea7456..be998b4bd 100644 --- a/third/CMakeLists.txt +++ b/third/CMakeLists.txt @@ -53,7 +53,7 @@ else () endif () qt5_use_modules(${EXECUTEABLE} Core)# Gui Widgets Network WebKit WebKitWidgets) -target_link_libraries(${EXECUTEABLE} webthree qethereum ethereum evm ethcore secp256k1 gmp ${CRYPTOPP_LS} serpent lll evmface devcore web3jsonrpc jsqrc) +target_link_libraries(${EXECUTEABLE} webthree qethereum ethereum evm ethcore secp256k1 gmp serpent lll evmface devcore web3jsonrpc jsqrc) if (APPLE) # First have qt5 install plugins and frameworks diff --git a/walleth/CMakeLists.txt b/walleth/CMakeLists.txt index cac73a726..26e010b97 100644 --- a/walleth/CMakeLists.txt +++ b/walleth/CMakeLists.txt @@ -59,7 +59,7 @@ else () endif () qt5_use_modules(${EXECUTEABLE} Core Gui Widgets Network Quick Qml) -target_link_libraries(${EXECUTEABLE} qethereum ethereum secp256k1 ${CRYPTOPP_LS}) +target_link_libraries(${EXECUTEABLE} qethereum ethereum secp256k1) if (APPLE) if (${ADDFRAMEWORKS}) From 69c499e01fe0edf42f8323398d2fd74a207baccf Mon Sep 17 00:00:00 2001 From: sveneh Date: Mon, 10 Nov 2014 16:41:25 +0100 Subject: [PATCH 020/277] provided my own FindJsonRCP.cmake --- cmake/FindJsonRcpCpp.cmake | 46 ++++++++++++++++++++++++++++++++++++++ extdep/json-rpc-cpp.cmake | 11 --------- 2 files changed, 46 insertions(+), 11 deletions(-) create mode 100644 cmake/FindJsonRcpCpp.cmake delete mode 100644 extdep/json-rpc-cpp.cmake diff --git a/cmake/FindJsonRcpCpp.cmake b/cmake/FindJsonRcpCpp.cmake new file mode 100644 index 000000000..1a7d45069 --- /dev/null +++ b/cmake/FindJsonRcpCpp.cmake @@ -0,0 +1,46 @@ +# Find json-rcp-cpp +# +# Find the JSONCpp includes and library +# +# if you nee to add a custom library search path, do it via via CMAKE_FIND_ROOT_PATH +# +# This module defines +# JSON_RCP_CPP_INCLUDE_DIRS, where to find json.h, etc. +# JSON_RCP_CPP_LIBRARIES, the libraries needed to use jsoncpp. +# JSON_RCP_CPP_FOUND, If false, do not try to use jsoncpp. + +if (JSON_RPC_CPP_LIBRARIES AND JSON_RPC_CPP_INCLUDE_DIRS) + # in cache already + set(JSON_RPC_CPP_FOUND TRUE) +endif() + + +# only look in default directories +find_path( + JSON_RPC_CPP_INCLUDE_DIR + NAMES jsonrpc/rpc.h + PATH_SUFFIXES jsonrpc + DOC "json-rpc-cpp include dir" +) + +find_library( + JSON_RPC_CPP_LIBRARY + NAMES jsonrpc + DOC "json-rpc-cpp library" +) + +set (JSON_RPC_CPP_INCLUDE_DIRS ${JSON_RPC_CPP_INCLUDE_DIR}) +set (JSON_RPC_CPP_LIBRARIES ${JSON_RPC_CPP_LIBRARY}) + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set JSON_RPC_CPP_FOUND to TRUE +# if all listed variables are TRUE +find_package_handle_standard_args(json-rpc-cpp DEFAULT_MSG + JSON_RPC_CPP_LIBRARY JSON_RPC_CPP_INCLUDE_DIR) + + +# include(FindPackageMessage) +# find_package_message ("json-rpc-cpp" "found" "bla") + + +mark_as_advanced (JSON_RPC_CPP_INCLUDE_DIR JSON_RPC_CPP_LIBRARY) diff --git a/extdep/json-rpc-cpp.cmake b/extdep/json-rpc-cpp.cmake deleted file mode 100644 index 28c5f7cf1..000000000 --- a/extdep/json-rpc-cpp.cmake +++ /dev/null @@ -1,11 +0,0 @@ -ExternalProject_Add(json-rpc-cpp - DEPENDS curl - GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git - GIT_TAG eaca2481e2889d5a5b748383fb02b1d395969cd4 - BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp - CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR} -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev . - BUILD_COMMAND make jsonrpc -j 3 - INSTALL_COMMAND make install - ) - - From 8ee3e56e0ae527fbd67dcb4a9a7adefb36a906aa Mon Sep 17 00:00:00 2001 From: sveneh Date: Mon, 10 Nov 2014 19:14:01 +0100 Subject: [PATCH 021/277] WIP: Cryptopp and json-rpc-cpp correctly downloading and compiling on Linux. Main cpp-ethereum buildfile finds dependencies, but does not compile yet --- CMakeLists.txt | 3 --- cmake/EthDependencies.cmake | 15 ++++++++--- cmake/EthDependenciesDeprecated.cmake | 26 ------------------- cmake/FindCryptoPP.cmake | 2 +- ...dJsonRcpCpp.cmake => FindJsonRpcCpp.cmake} | 12 ++++----- extdep/CMakeLists.txt | 5 ++-- extdep/FindCURL.cmake | 2 +- extdep/curl.cmake | 18 +++++++++---- extdep/json-rpc-cpp.cmake | 11 ++++++++ 9 files changed, 44 insertions(+), 50 deletions(-) rename cmake/{FindJsonRcpCpp.cmake => FindJsonRpcCpp.cmake} (85%) create mode 100644 extdep/json-rpc-cpp.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index f3de28909..34a2447b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -149,9 +149,6 @@ if (NOT LANGUAGES) if ("${TARGET_PLATFORM}" STREQUAL "w64") cmake_policy(SET CMP0020 NEW) endif () - if (NOT JSONRPC_LS) - message(FATAL_ERROR "Alethzero requires jsonrpc.") - endif() add_subdirectory(libjsqrc) add_subdirectory(libqethereum) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 5934b1512..376a6c03f 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -1,11 +1,18 @@ # all dependencies that are not directly included in the cpp-ethereum distribution are defined here # for this to work, download the dependency via the cmake script in extdep or install them manually! -set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install") +# by defining this variable, cmake will look for dependencies first in our own repository before looking in system paths like /usr/local/ ... +# this must be set to point to the same directory as $ETH_DEPENDENCY_INSTALL_DIR in /extdep directory +set (CMAKE_FIND_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install") -set (CRYPTOPP_ROOT_DIR ${ETH_DEPENDENCY_INSTALL_DIR}) find_package (CryptoPP 5.6.2 REQUIRED) -message("-- CryptoPP header: ${CRYPTOPP_INCLUDE_DIRS}") -message("-- CryptoPP libs : ${CRYPTOPP_LIBRARIES}") +message(" - CryptoPP header: ${CRYPTOPP_INCLUDE_DIRS}") +message(" - CryptoPP lib : ${CRYPTOPP_LIBRARIES}") +find_package (JsonRpcCpp REQUIRED) +if (${JSON_RPC_CPP_FOUND}) + message (" - json-rpc-cpp header: ${JSON_RPC_CPP_INCLUDE_DIRS}") + message (" - json-rpc-cpp lib : ${JSON_RPC_CPP_LIBRARIES}") + add_definitions(-DETH_JSONRPC) +endif() diff --git a/cmake/EthDependenciesDeprecated.cmake b/cmake/EthDependenciesDeprecated.cmake index 4be546a13..aacb625db 100644 --- a/cmake/EthDependenciesDeprecated.cmake +++ b/cmake/EthDependenciesDeprecated.cmake @@ -85,29 +85,6 @@ else() message(STATUS "Failed to find the miniupnpc headers!") endif () - find_path( JSONRPC_ID jsonrpc/rpc.h - /usr/include - /usr/local/include - ) - if ( JSONRPC_ID ) - message(STATUS "Found jsonrpc headers") - find_library( JSONRPC_LS NAMES jsonrpc - PATHS - /usr/lib - /usr/local/lib - /opt/local/lib - /usr/lib/*/ - ) - if ( JSONRPC_LS ) - message(STATUS "Found jsonrpc library: ${JSONRPC_LS}") - add_definitions(-DETH_JSONRPC) - else () - message(STATUS "Failed to find the jsonrpc library!") - endif () - else () - message(STATUS "Failed to find the jsonrpc headers!") - endif () - find_path( READLINE_ID readline/readline.h /usr/include /usr/local/include @@ -152,9 +129,6 @@ endif() if(READLINE_ID) include_directories(${READLINE_ID}) endif() -if(JSONRPC_ID) - include_directories(${JSONRPC_ID}) -endif() diff --git a/cmake/FindCryptoPP.cmake b/cmake/FindCryptoPP.cmake index 74a01e83a..a9e7183c0 100644 --- a/cmake/FindCryptoPP.cmake +++ b/cmake/FindCryptoPP.cmake @@ -104,5 +104,5 @@ SET (CRYPTOPP_LIBRARIES ${CRYPTOPP_LIBRARY}) MARK_AS_ADVANCED (CRYPTOPP_INCLUDE_DIR CRYPTOPP_LIBRARY CRYPTOPP_LIBRARY_DEBUG CRYPTOPP_LIBRARY_RELEASE) -FIND_PACKAGE_HANDLE_STANDARD_ARGS (CryptoPP REQUIRED_VARS CRYPTOPP_ROOT_DIR +FIND_PACKAGE_HANDLE_STANDARD_ARGS (CryptoPP REQUIRED_VARS CRYPTOPP_INCLUDE_DIR CRYPTOPP_LIBRARY VERSION_VAR CRYPTOPP_VERSION) diff --git a/cmake/FindJsonRcpCpp.cmake b/cmake/FindJsonRpcCpp.cmake similarity index 85% rename from cmake/FindJsonRcpCpp.cmake rename to cmake/FindJsonRpcCpp.cmake index 1a7d45069..c056418b0 100644 --- a/cmake/FindJsonRcpCpp.cmake +++ b/cmake/FindJsonRpcCpp.cmake @@ -9,12 +9,6 @@ # JSON_RCP_CPP_LIBRARIES, the libraries needed to use jsoncpp. # JSON_RCP_CPP_FOUND, If false, do not try to use jsoncpp. -if (JSON_RPC_CPP_LIBRARIES AND JSON_RPC_CPP_INCLUDE_DIRS) - # in cache already - set(JSON_RPC_CPP_FOUND TRUE) -endif() - - # only look in default directories find_path( JSON_RPC_CPP_INCLUDE_DIR @@ -32,10 +26,14 @@ find_library( set (JSON_RPC_CPP_INCLUDE_DIRS ${JSON_RPC_CPP_INCLUDE_DIR}) set (JSON_RPC_CPP_LIBRARIES ${JSON_RPC_CPP_LIBRARY}) +# message (" - json-rcp-cpp header : ${JSON_RPC_CPP_INCLUDE_DIRS}") +# message (" - json-rcp-cpp lib : ${JSON_RPC_CPP_LIBRARIES}") + + include(FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set JSON_RPC_CPP_FOUND to TRUE # if all listed variables are TRUE -find_package_handle_standard_args(json-rpc-cpp DEFAULT_MSG +find_package_handle_standard_args(json_rpc_cpp DEFAULT_MSG JSON_RPC_CPP_LIBRARY JSON_RPC_CPP_INCLUDE_DIR) diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index 121f21067..666ea5f15 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -2,13 +2,12 @@ cmake_minimum_required(VERSION 2.8) include(ExternalProject) -# dependencies will be installed into this directory +# all dependencies will be installed into this directory set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install") - file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}) include(cryptopp.cmake) include(curl.cmake) include(json-rpc-cpp.cmake) -include(miniupnpc.cmake) +#include(miniupnpc.cmake) diff --git a/extdep/FindCURL.cmake b/extdep/FindCURL.cmake index 6a82ebb22..22d51591c 100644 --- a/extdep/FindCURL.cmake +++ b/extdep/FindCURL.cmake @@ -1,4 +1,4 @@ -# hacky way to resolve nested dependencies +# hacky way to resolve nested dependencies - needed for json-rpc-cpp find_library(CURL_LIBRARY NAMES curl PATHS ${ETH_DEPENDENCY_INSTALL_DIR}/lib diff --git a/extdep/curl.cmake b/extdep/curl.cmake index 5d915c79b..13e10361d 100644 --- a/extdep/curl.cmake +++ b/extdep/curl.cmake @@ -1,12 +1,20 @@ + +set (CONFIG_CMD ./configure --prefix=${ETH_DEPENDENCY_INSTALL_DIR} --exec-prefix=${ETH_DEPENDENCY_INSTALL_DIR}) + if(${APPLE}) -ExternalProject_Add(curl + set(CONFIG_CMD ./configure --with-darwinssl --prefix=${ETH_DEPENDENCY_INSTALL_DIR} --exec-prefix=${ETH_DEPENDENCY_INSTALL_DIR}) +endif() + + + +ExternalProject_Add( + curl URL http://curl.haxx.se/download/curl-7.38.0.tar.bz2 BINARY_DIR curl-prefix/src/curl - CONFIGURE_COMMAND ./configure --with-darwinssl --prefix=${ETH_DEPENDENCY_INSTALL_DIR} --exec-prefix=${ETH_DEPENDENCY_INSTALL_DIR} + CONFIGURE_COMMAND ${CONFIG_CMD} BUILD_COMMAND make -j 3 INSTALL_COMMAND make install - ) -else() +) + -endif() diff --git a/extdep/json-rpc-cpp.cmake b/extdep/json-rpc-cpp.cmake new file mode 100644 index 000000000..28c5f7cf1 --- /dev/null +++ b/extdep/json-rpc-cpp.cmake @@ -0,0 +1,11 @@ +ExternalProject_Add(json-rpc-cpp + DEPENDS curl + GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git + GIT_TAG eaca2481e2889d5a5b748383fb02b1d395969cd4 + BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp + CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR} -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev . + BUILD_COMMAND make jsonrpc -j 3 + INSTALL_COMMAND make install + ) + + From b82e3125ce74880a532c9e7d4b7c7f708a9bc283 Mon Sep 17 00:00:00 2001 From: sveneh Date: Mon, 10 Nov 2014 20:31:15 +0100 Subject: [PATCH 022/277] compiles fine now (on Linux) with both cryptopp and json-rpc-cpp dependencies --- CMakeLists.txt | 8 ++++++-- eth/CMakeLists.txt | 2 +- libweb3jsonrpc/CMakeLists.txt | 4 +--- neth/CMakeLists.txt | 2 +- test/CMakeLists.txt | 2 +- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 34a2447b2..a44fd1591 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -118,7 +118,7 @@ endif() add_subdirectory(lllc) add_subdirectory(solc) add_subdirectory(sc) -if (JSONRPC_LS) +if (JSON_RPC_CPP_FOUND) add_subdirectory(libweb3jsonrpc) endif() if (NOT LANGUAGES) @@ -152,7 +152,11 @@ if (NOT LANGUAGES) add_subdirectory(libjsqrc) add_subdirectory(libqethereum) - add_subdirectory(alethzero) + if (NOT JSON_RPC_CPP_FOUND) + message (FATAL_ERROR "AlethZero requires json-rpc-cpp!") + else() + add_subdirectory(alethzero) + endif() add_subdirectory(third) if(QTQML) #add_subdirectory(iethxi) diff --git a/eth/CMakeLists.txt b/eth/CMakeLists.txt index 793223abd..cb3b01b4e 100644 --- a/eth/CMakeLists.txt +++ b/eth/CMakeLists.txt @@ -16,7 +16,7 @@ if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) -if(JSONRPC_LS) +if(JSON_RPC_CPP_FOUND) target_link_libraries(${EXECUTABLE} web3jsonrpc) endif() if(READLINE_LS) diff --git a/libweb3jsonrpc/CMakeLists.txt b/libweb3jsonrpc/CMakeLists.txt index b24a11196..4184d7cbd 100644 --- a/libweb3jsonrpc/CMakeLists.txt +++ b/libweb3jsonrpc/CMakeLists.txt @@ -22,9 +22,7 @@ if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) -target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) -target_link_libraries(${EXECUTABLE} ${JSONRPC_LS}) -target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) +target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_LIBRARIES}) if(READLINE_LS) target_link_libraries(${EXECUTABLE} ${READLINE_LS}) endif() diff --git a/neth/CMakeLists.txt b/neth/CMakeLists.txt index 68044fe7c..d9f551b18 100644 --- a/neth/CMakeLists.txt +++ b/neth/CMakeLists.txt @@ -17,7 +17,7 @@ if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) -if(JSONRPC_LS) +if(JSON_RPC_CPP_FOUND) target_link_libraries(${EXECUTABLE} web3jsonrpc) endif() diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4f02f96bb..38e3ca1ca 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -21,7 +21,7 @@ target_link_libraries(testeth webthree) #TODO this on should not be necessary, it should have been brought in from ethcore dependency... target_link_libraries(testeth ${CRYPTOPP_LIBRARIES}) -if(JSONRPC_LS) +if(JSON_RPC_CPP_FOUND) target_link_libraries(testeth web3jsonrpc) endif() From 369670a6d9dffe8aa9612172a7cc81f531173d91 Mon Sep 17 00:00:00 2001 From: sveneh Date: Thu, 13 Nov 2014 12:02:37 +0100 Subject: [PATCH 023/277] changes from debris, to allow build on Mac OS --- extdep/cryptopp.cmake | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/extdep/cryptopp.cmake b/extdep/cryptopp.cmake index 0f83d0115..39a848649 100644 --- a/extdep/cryptopp.cmake +++ b/extdep/cryptopp.cmake @@ -1,11 +1,11 @@ if(${APPLE}) ExternalProject_Add(cryptopp - URL http://www.cryptopp.com/cryptopp562.zip - BINARY_DIR cryptopp-prefix/src/cryptopp - CONFIGURE_COMMAND "" - BUILD_COMMAND make -j 3 - INSTALL_COMMAND make dynamic install PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} - ) + URL https://downloads.sourceforge.net/project/cryptopp/cryptopp/5.6.2/cryptopp562.zip + BINARY_DIR cryptopp-prefix/src/cryptopp + CONFIGURE_COMMAND "" + BUILD_COMMAND make CXX=clang++ CXXFLAGS=-DCRYPTOPP_DISABLE_ASM + INSTALL_COMMAND make install PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} +) else() ExternalProject_Add(cryptopp URL https://github.com/mmoss/cryptopp/archive/v5.6.2.zip From 888bdd03dcd9a56d170e48ec23af4dd950066a7d Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 12 Nov 2014 17:51:37 +0100 Subject: [PATCH 024/277] jsonrpccpp 0.2.1 with patch for osx 10.9 --- extdep/json-rpc-cpp.cmake | 4 ++-- extdep/json-rpc-cpp_osx.patch | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 extdep/json-rpc-cpp_osx.patch diff --git a/extdep/json-rpc-cpp.cmake b/extdep/json-rpc-cpp.cmake index 28c5f7cf1..ea26851b9 100644 --- a/extdep/json-rpc-cpp.cmake +++ b/extdep/json-rpc-cpp.cmake @@ -1,9 +1,9 @@ ExternalProject_Add(json-rpc-cpp DEPENDS curl GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git - GIT_TAG eaca2481e2889d5a5b748383fb02b1d395969cd4 + GIT_TAG 0.2.1 BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp - CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR} -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev . + CONFIGURE_COMMAND patch -d src/example < ${CMAKE_CURRENT_SOURCE_DIR}/json-rpc-cpp_osx.patch && cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR} -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev . BUILD_COMMAND make jsonrpc -j 3 INSTALL_COMMAND make install ) diff --git a/extdep/json-rpc-cpp_osx.patch b/extdep/json-rpc-cpp_osx.patch new file mode 100644 index 000000000..39165530d --- /dev/null +++ b/extdep/json-rpc-cpp_osx.patch @@ -0,0 +1,9 @@ +--- ./src/example/CMakeLists.txt 2014-11-12 17:20:52.000000000 +0100 ++++ CMakeListsPatch.txt 2014-11-12 17:26:42.000000000 +0100 +@@ -12,6 +12,3 @@ + add_executable(stubserversample stubserver.cpp) + target_link_libraries(stubserversample jsonrpc) + +- +-add_executable(xbmcremote xbmcremote.cpp) +-target_link_libraries(xbmcremote jsonrpc) From 2c340cd2c1b8a96063c01d9b3fbb6e3de0a8ceaf Mon Sep 17 00:00:00 2001 From: sveneh Date: Sun, 16 Nov 2014 21:25:35 +0100 Subject: [PATCH 025/277] Fixed issues caused by downgrading json-rpc-cpp to 0.2.1 introduced platform-specific direcory in extdep/install/ --- cmake/EthDependencies.cmake | 10 +++++++--- eth/CMakeLists.txt | 1 + extdep/CMakeLists.txt | 6 ++++-- extdep/cryptopp.cmake | 29 ++++++++++++++++------------- extdep/curl.cmake | 15 ++++----------- extdep/json-rpc-cpp.cmake | 18 ++++++++++++++---- extdep/json-rpc-cpp_linux.patch | 13 +++++++++++++ neth/CMakeLists.txt | 1 + 8 files changed, 60 insertions(+), 33 deletions(-) create mode 100644 extdep/json-rpc-cpp_linux.patch diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 376a6c03f..09de078c0 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -3,14 +3,18 @@ # by defining this variable, cmake will look for dependencies first in our own repository before looking in system paths like /usr/local/ ... # this must be set to point to the same directory as $ETH_DEPENDENCY_INSTALL_DIR in /extdep directory -set (CMAKE_FIND_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install") +string(TOLOWER ${CMAKE_SYSTEM_NAME} system_name) +set (CMAKE_FIND_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install/${system_name}") -find_package (CryptoPP 5.6.2 REQUIRED) + +# Dependencies must have a version number + EXACT, to ensure reproducible builds + +find_package (CryptoPP 5.6.2 EXACT REQUIRED) message(" - CryptoPP header: ${CRYPTOPP_INCLUDE_DIRS}") message(" - CryptoPP lib : ${CRYPTOPP_LIBRARIES}") -find_package (JsonRpcCpp REQUIRED) +find_package (JsonRpcCpp 0.2.1 EXACT REQUIRED) if (${JSON_RPC_CPP_FOUND}) message (" - json-rpc-cpp header: ${JSON_RPC_CPP_INCLUDE_DIRS}") message (" - json-rpc-cpp lib : ${JSON_RPC_CPP_LIBRARIES}") diff --git a/eth/CMakeLists.txt b/eth/CMakeLists.txt index cb3b01b4e..fbd7d6835 100644 --- a/eth/CMakeLists.txt +++ b/eth/CMakeLists.txt @@ -3,6 +3,7 @@ cmake_policy(SET CMP0015 NEW) aux_source_directory(. SRC_LIST) include_directories(..) +include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) set(EXECUTABLE eth) diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index 666ea5f15..88f4fba0a 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -2,8 +2,10 @@ cmake_minimum_required(VERSION 2.8) include(ExternalProject) -# all dependencies will be installed into this directory -set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install") + +# all dependencies will be installed into this directory, separated by platform +string(TOLOWER ${CMAKE_SYSTEM_NAME} SYSTEM_NAME) +set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install/${SYSTEM_NAME}") file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}) include(cryptopp.cmake) diff --git a/extdep/cryptopp.cmake b/extdep/cryptopp.cmake index 39a848649..3a1513e29 100644 --- a/extdep/cryptopp.cmake +++ b/extdep/cryptopp.cmake @@ -1,18 +1,21 @@ -if(${APPLE}) -ExternalProject_Add(cryptopp - URL https://downloads.sourceforge.net/project/cryptopp/cryptopp/5.6.2/cryptopp562.zip - BINARY_DIR cryptopp-prefix/src/cryptopp - CONFIGURE_COMMAND "" - BUILD_COMMAND make CXX=clang++ CXXFLAGS=-DCRYPTOPP_DISABLE_ASM - INSTALL_COMMAND make install PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} +# CryptoPP does not have good cross-platform support, there exist several different other projects to make it work ... + +if(APPLE) + ExternalProject_Add(cryptopp + URL https://downloads.sourceforge.net/project/cryptopp/cryptopp/5.6.2/cryptopp562.zip + BINARY_DIR cryptopp-prefix/src/cryptopp + CONFIGURE_COMMAND "" + BUILD_COMMAND make CXX=clang++ CXXFLAGS=-DCRYPTOPP_DISABLE_ASM + INSTALL_COMMAND make install PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} ) +# on Linux, the default Makefile does not work. else() -ExternalProject_Add(cryptopp - URL https://github.com/mmoss/cryptopp/archive/v5.6.2.zip - BINARY_DIR cryptopp-prefix/src/cryptopp - CONFIGURE_COMMAND "" - BUILD_COMMAND scons --shared --prefix=${ETH_DEPENDENCY_INSTALL_DIR} - INSTALL_COMMAND "" + ExternalProject_Add(cryptopp + URL https://github.com/mmoss/cryptopp/archive/v5.6.2.zip + BINARY_DIR cryptopp-prefix/src/cryptopp + CONFIGURE_COMMAND "" + BUILD_COMMAND scons --shared --prefix=${ETH_DEPENDENCY_INSTALL_DIR} + INSTALL_COMMAND "" ) endif() diff --git a/extdep/curl.cmake b/extdep/curl.cmake index 13e10361d..fa06d7ba0 100644 --- a/extdep/curl.cmake +++ b/extdep/curl.cmake @@ -1,20 +1,13 @@ - -set (CONFIG_CMD ./configure --prefix=${ETH_DEPENDENCY_INSTALL_DIR} --exec-prefix=${ETH_DEPENDENCY_INSTALL_DIR}) - -if(${APPLE}) +if(APPLE) set(CONFIG_CMD ./configure --with-darwinssl --prefix=${ETH_DEPENDENCY_INSTALL_DIR} --exec-prefix=${ETH_DEPENDENCY_INSTALL_DIR}) +else() + set (CONFIG_CMD ./configure --prefix=${ETH_DEPENDENCY_INSTALL_DIR} --exec-prefix=${ETH_DEPENDENCY_INSTALL_DIR}) endif() - - -ExternalProject_Add( - curl +ExternalProject_Add(curl URL http://curl.haxx.se/download/curl-7.38.0.tar.bz2 BINARY_DIR curl-prefix/src/curl CONFIGURE_COMMAND ${CONFIG_CMD} BUILD_COMMAND make -j 3 INSTALL_COMMAND make install ) - - - diff --git a/extdep/json-rpc-cpp.cmake b/extdep/json-rpc-cpp.cmake index ea26851b9..8d3b29c19 100644 --- a/extdep/json-rpc-cpp.cmake +++ b/extdep/json-rpc-cpp.cmake @@ -1,11 +1,21 @@ +# json-rpc-cpp is under heavy development, and multiplatform builds are not yet available. All the platforms currently need patches to make them work. + +if(APPLE) + set(PATCH_CMD patch -d src/example < ${CMAKE_CURRENT_SOURCE_DIR}/json-rpc-cpp_osx.patch) + set(CONFIG_CMD cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR} -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev .) +else() + set(PATCH_CMD patch --input=${CMAKE_CURRENT_SOURCE_DIR}/json-rpc-cpp_linux.patch --strip=1) + set(CONFIG_CMD cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR} -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST .) +endif() + + ExternalProject_Add(json-rpc-cpp DEPENDS curl GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git GIT_TAG 0.2.1 BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp - CONFIGURE_COMMAND patch -d src/example < ${CMAKE_CURRENT_SOURCE_DIR}/json-rpc-cpp_osx.patch && cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR} -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev . + PATCH_COMMAND ${PATCH_CMD} + CONFIGURE_COMMAND ${CONFIG_CMD} BUILD_COMMAND make jsonrpc -j 3 INSTALL_COMMAND make install - ) - - +) diff --git a/extdep/json-rpc-cpp_linux.patch b/extdep/json-rpc-cpp_linux.patch new file mode 100644 index 000000000..40662f2a8 --- /dev/null +++ b/extdep/json-rpc-cpp_linux.patch @@ -0,0 +1,13 @@ +diff --git a/src/jsonrpc/CMakeLists.txt b/src/jsonrpc/CMakeLists.txt +index 79e8515..4e93eef 100644 +--- a/src/jsonrpc/CMakeLists.txt ++++ b/src/jsonrpc/CMakeLists.txt +@@ -12,7 +12,7 @@ set(VERSION_STRING ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}) + set_target_properties(jsonrpc jsonrpcStatic PROPERTIES VERSION "${VERSION_STRING}" SOVERSION "${VERSION_MAJOR}") + + +-target_link_libraries(jsonrpc ${CURL_LIBRARIES}) ++target_link_libraries(jsonrpc ${CURL_LIBRARIES} dl pthread) + target_link_libraries(jsonrpcStatic ${CURL_LIBRARIES}) + + install(FILES ${jsonrpc_header} DESTINATION include/jsonrpc) diff --git a/neth/CMakeLists.txt b/neth/CMakeLists.txt index d9f551b18..bef34c4e3 100644 --- a/neth/CMakeLists.txt +++ b/neth/CMakeLists.txt @@ -4,6 +4,7 @@ aux_source_directory(. SRC_LIST) include_directories(..) include_directories(${LEVELDB_ID}) +include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) set(EXECUTABLE neth) From a66d369926b08e704d23c5ba13a1a399457e7538 Mon Sep 17 00:00:00 2001 From: sveneh Date: Tue, 18 Nov 2014 10:44:30 +0100 Subject: [PATCH 026/277] switched to a fork of json-rpc-cpp, roughly resembling v0.3.2. This fork has already preliminary windows support --- extdep/CMakeLists.txt | 3 ++- extdep/json-rpc-cpp.cmake | 14 ++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index 88f4fba0a..d2245277f 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -9,7 +9,8 @@ set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install/${SYSTEM_NAM file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}) include(cryptopp.cmake) -include(curl.cmake) +# will be re-eanbled later +# include(curl.cmake) include(json-rpc-cpp.cmake) #include(miniupnpc.cmake) diff --git a/extdep/json-rpc-cpp.cmake b/extdep/json-rpc-cpp.cmake index 8d3b29c19..165a07ff4 100644 --- a/extdep/json-rpc-cpp.cmake +++ b/extdep/json-rpc-cpp.cmake @@ -1,21 +1,19 @@ -# json-rpc-cpp is under heavy development, and multiplatform builds are not yet available. All the platforms currently need patches to make them work. +# json-rpc-cpp is under heavy development, and multiplatform builds are not yet available. +# we use a forked repository which already has preliminary windows support if(APPLE) - set(PATCH_CMD patch -d src/example < ${CMAKE_CURRENT_SOURCE_DIR}/json-rpc-cpp_osx.patch) set(CONFIG_CMD cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR} -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev .) else() - set(PATCH_CMD patch --input=${CMAKE_CURRENT_SOURCE_DIR}/json-rpc-cpp_linux.patch --strip=1) set(CONFIG_CMD cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR} -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST .) endif() ExternalProject_Add(json-rpc-cpp - DEPENDS curl - GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git - GIT_TAG 0.2.1 + # DEPENDS curl # re-enable later, when we build curl again + GIT_REPOSITORY https://github.com/gogo40/libjson-rpc-cpp.git + GIT_TAG 27f5da7a70c7a82b0614982cac829d6fd5fc8314 # this is roughly verson 0.3.2 BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp - PATCH_COMMAND ${PATCH_CMD} CONFIGURE_COMMAND ${CONFIG_CMD} - BUILD_COMMAND make jsonrpc -j 3 + BUILD_COMMAND make -j 3 INSTALL_COMMAND make install ) From 28d69e0981e575fd1a68e39a2683808f7aebf432 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 18 Nov 2014 11:46:57 +0100 Subject: [PATCH 027/277] common changes --- alethzero/OurWebThreeStubServer.cpp | 2 +- alethzero/OurWebThreeStubServer.h | 2 +- test/jsonrpc.cpp | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/alethzero/OurWebThreeStubServer.cpp b/alethzero/OurWebThreeStubServer.cpp index a40727e1e..fec0f9e8d 100644 --- a/alethzero/OurWebThreeStubServer.cpp +++ b/alethzero/OurWebThreeStubServer.cpp @@ -24,7 +24,7 @@ using namespace std; using namespace dev; using namespace dev::eth; -OurWebThreeStubServer::OurWebThreeStubServer(jsonrpc::AbstractServerConnector* _conn, dev::WebThreeDirect& _web3, std::vector const& _accounts): +OurWebThreeStubServer::OurWebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, dev::WebThreeDirect& _web3, std::vector const& _accounts): WebThreeStubServer(_conn, _web3, _accounts) {} diff --git a/alethzero/OurWebThreeStubServer.h b/alethzero/OurWebThreeStubServer.h index b3492df5e..ef13964b9 100644 --- a/alethzero/OurWebThreeStubServer.h +++ b/alethzero/OurWebThreeStubServer.h @@ -29,7 +29,7 @@ class OurWebThreeStubServer: public QObject, public WebThreeStubServer Q_OBJECT public: - OurWebThreeStubServer(jsonrpc::AbstractServerConnector* _conn, dev::WebThreeDirect& _web3, std::vector const& _accounts); + OurWebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, dev::WebThreeDirect& _web3, std::vector const& _accounts); virtual std::string shh_newIdentity() override; diff --git a/test/jsonrpc.cpp b/test/jsonrpc.cpp index 4c748a954..727791f6e 100644 --- a/test/jsonrpc.cpp +++ b/test/jsonrpc.cpp @@ -29,8 +29,8 @@ #include #include #include -#include -#include +#include +#include #include #include "JsonSpiritHeaders.h" #include "TestHelper.h" @@ -61,11 +61,11 @@ struct Setup web3->setIdealPeerCount(5); web3->ethereum()->setForceMining(true); - jsonrpcServer = unique_ptr(new WebThreeStubServer(new jsonrpc::CorsHttpServer(8080), *web3, {})); + jsonrpcServer = unique_ptr(new WebThreeStubServer(jsonrpc::CorsHttpServer(8080), *web3, {})); jsonrpcServer->setIdentities({}); jsonrpcServer->StartListening(); - jsonrpcClient = unique_ptr(new WebThreeStubClient(new jsonrpc::HttpClient("http://localhost:8080"))); + jsonrpcClient = unique_ptr(new WebThreeStubClient(jsonrpc::HttpClient("http://localhost:8080"))); } }; From cc92d2e501ae300c145437936a4ed622b4459aa8 Mon Sep 17 00:00:00 2001 From: sveneh Date: Tue, 18 Nov 2014 12:09:53 +0100 Subject: [PATCH 028/277] changed the source repository for libjson-rpc-cpp AGAIN, as the forked one did not build on OS X. Back to the official repo again. Windows support we will have to do ourself. --- extdep/json-rpc-cpp.cmake | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/extdep/json-rpc-cpp.cmake b/extdep/json-rpc-cpp.cmake index 165a07ff4..810fd3a0a 100644 --- a/extdep/json-rpc-cpp.cmake +++ b/extdep/json-rpc-cpp.cmake @@ -1,5 +1,5 @@ -# json-rpc-cpp is under heavy development, and multiplatform builds are not yet available. -# we use a forked repository which already has preliminary windows support +# json-rpc-cpp is under heavy development, not yet stable, and multiplatform builds are not yet available. +# DO NOT MESS WITH THESE SETTINGS! IF YOU HAVE TO MAKE CHANGES HERE, CONSULT sven@ethdev.com BEFOREHAND!! if(APPLE) set(CONFIG_CMD cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR} -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev .) @@ -8,10 +8,11 @@ else() endif() +# DO NOT CHANGE ANYTHING HERE! ExternalProject_Add(json-rpc-cpp # DEPENDS curl # re-enable later, when we build curl again - GIT_REPOSITORY https://github.com/gogo40/libjson-rpc-cpp.git - GIT_TAG 27f5da7a70c7a82b0614982cac829d6fd5fc8314 # this is roughly verson 0.3.2 + GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git + GIT_TAG v0.3.2 BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp CONFIGURE_COMMAND ${CONFIG_CMD} BUILD_COMMAND make -j 3 From 67bc10efd67a43fb5f27d5d731210487af508b66 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 18 Nov 2014 12:22:10 +0100 Subject: [PATCH 029/277] fixed test --- test/jsonrpc.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/jsonrpc.cpp b/test/jsonrpc.cpp index 727791f6e..25468dcc0 100644 --- a/test/jsonrpc.cpp +++ b/test/jsonrpc.cpp @@ -61,11 +61,12 @@ struct Setup web3->setIdealPeerCount(5); web3->ethereum()->setForceMining(true); - jsonrpcServer = unique_ptr(new WebThreeStubServer(jsonrpc::CorsHttpServer(8080), *web3, {})); + auto server = new jsonrpc::CorsHttpServer(8080); + jsonrpcServer = unique_ptr(new WebThreeStubServer(*server, *web3, {})); jsonrpcServer->setIdentities({}); jsonrpcServer->StartListening(); - - jsonrpcClient = unique_ptr(new WebThreeStubClient(jsonrpc::HttpClient("http://localhost:8080"))); + auto client = new jsonrpc::HttpClient("http://localhost:8080"); + jsonrpcClient = unique_ptr(new WebThreeStubClient(*client)); } }; From ddac0ebb31b205ec24573aba6729bfb3db928bd8 Mon Sep 17 00:00:00 2001 From: administrator Date: Thu, 20 Nov 2014 03:28:25 -0800 Subject: [PATCH 030/277] now also builds correctly on OS X --- extdep/cryptopp.cmake | 1 + libweb3jsonrpc/CMakeLists.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/extdep/cryptopp.cmake b/extdep/cryptopp.cmake index 3a1513e29..abb035c11 100644 --- a/extdep/cryptopp.cmake +++ b/extdep/cryptopp.cmake @@ -1,5 +1,6 @@ # CryptoPP does not have good cross-platform support, there exist several different other projects to make it work ... +# TODO the OS X build throws a lot of warnings, but compiles fine if(APPLE) ExternalProject_Add(cryptopp URL https://downloads.sourceforge.net/project/cryptopp/cryptopp/5.6.2/cryptopp562.zip diff --git a/libweb3jsonrpc/CMakeLists.txt b/libweb3jsonrpc/CMakeLists.txt index 8d45bcfd9..7d0695b30 100644 --- a/libweb3jsonrpc/CMakeLists.txt +++ b/libweb3jsonrpc/CMakeLists.txt @@ -25,6 +25,7 @@ if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) +target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_LIBRARIES}) if(READLINE_LS) target_link_libraries(${EXECUTABLE} ${READLINE_LS}) From 39f0fd1320a9b6c065113100b3a7875de937a6a0 Mon Sep 17 00:00:00 2001 From: sveneh Date: Thu, 20 Nov 2014 14:00:05 +0100 Subject: [PATCH 031/277] cleanup, Readme --- extdep/CMakeLists.txt | 4 ++-- extdep/Readme.md | 16 ++++++++++++++++ extdep/json-rpc-cpp_linux.patch | 13 ------------- extdep/json-rpc-cpp_osx.patch | 9 --------- 4 files changed, 18 insertions(+), 24 deletions(-) create mode 100644 extdep/Readme.md delete mode 100644 extdep/json-rpc-cpp_linux.patch delete mode 100644 extdep/json-rpc-cpp_osx.patch diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index d2245277f..5ef5e63d5 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -4,8 +4,8 @@ include(ExternalProject) # all dependencies will be installed into this directory, separated by platform -string(TOLOWER ${CMAKE_SYSTEM_NAME} SYSTEM_NAME) -set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install/${SYSTEM_NAME}") +string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name) +set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install/${_system_name}") file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}) include(cryptopp.cmake) diff --git a/extdep/Readme.md b/extdep/Readme.md new file mode 100644 index 000000000..1706f1fb9 --- /dev/null +++ b/extdep/Readme.md @@ -0,0 +1,16 @@ +# cpp-ethereum external dependencies + +**This is Work-in-Progress!** + +This directory hosts the external libraries that are needed to build cpp-ethereum. + +To automatically download, build, and link libraries, do +``` +cd extdep; mkdir build; cd build; cmake ..; make +``` +this will take some time. + + +To check which libraries are already included, check `CMakeLists.txt`. Other libraries still need to be fetched via the system's package manager. + +Libraries will be installed in `cpp-ethereum/extdep/install/` diff --git a/extdep/json-rpc-cpp_linux.patch b/extdep/json-rpc-cpp_linux.patch deleted file mode 100644 index 40662f2a8..000000000 --- a/extdep/json-rpc-cpp_linux.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/src/jsonrpc/CMakeLists.txt b/src/jsonrpc/CMakeLists.txt -index 79e8515..4e93eef 100644 ---- a/src/jsonrpc/CMakeLists.txt -+++ b/src/jsonrpc/CMakeLists.txt -@@ -12,7 +12,7 @@ set(VERSION_STRING ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}) - set_target_properties(jsonrpc jsonrpcStatic PROPERTIES VERSION "${VERSION_STRING}" SOVERSION "${VERSION_MAJOR}") - - --target_link_libraries(jsonrpc ${CURL_LIBRARIES}) -+target_link_libraries(jsonrpc ${CURL_LIBRARIES} dl pthread) - target_link_libraries(jsonrpcStatic ${CURL_LIBRARIES}) - - install(FILES ${jsonrpc_header} DESTINATION include/jsonrpc) diff --git a/extdep/json-rpc-cpp_osx.patch b/extdep/json-rpc-cpp_osx.patch deleted file mode 100644 index 39165530d..000000000 --- a/extdep/json-rpc-cpp_osx.patch +++ /dev/null @@ -1,9 +0,0 @@ ---- ./src/example/CMakeLists.txt 2014-11-12 17:20:52.000000000 +0100 -+++ CMakeListsPatch.txt 2014-11-12 17:26:42.000000000 +0100 -@@ -12,6 +12,3 @@ - add_executable(stubserversample stubserver.cpp) - target_link_libraries(stubserversample jsonrpc) - -- --add_executable(xbmcremote xbmcremote.cpp) --target_link_libraries(xbmcremote jsonrpc) From e29befcb960f37d7801ec9ce9d9352f9a7211238 Mon Sep 17 00:00:00 2001 From: debris Date: Mon, 24 Nov 2014 09:08:41 +0100 Subject: [PATCH 032/277] cryptopp msbuild --- extdep/CMakeLists.txt | 5 +++-- extdep/cryptopp.cmake | 25 ++++++++++++++++++------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index 5ef5e63d5..7551d2e98 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -6,11 +6,12 @@ include(ExternalProject) # all dependencies will be installed into this directory, separated by platform string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name) set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install/${_system_name}") -file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}) +file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/lib) +file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include) include(cryptopp.cmake) # will be re-eanbled later # include(curl.cmake) -include(json-rpc-cpp.cmake) +#include(json-rpc-cpp.cmake) #include(miniupnpc.cmake) diff --git a/extdep/cryptopp.cmake b/extdep/cryptopp.cmake index abb035c11..9f54244bc 100644 --- a/extdep/cryptopp.cmake +++ b/extdep/cryptopp.cmake @@ -3,12 +3,23 @@ # TODO the OS X build throws a lot of warnings, but compiles fine if(APPLE) ExternalProject_Add(cryptopp - URL https://downloads.sourceforge.net/project/cryptopp/cryptopp/5.6.2/cryptopp562.zip - BINARY_DIR cryptopp-prefix/src/cryptopp - CONFIGURE_COMMAND "" - BUILD_COMMAND make CXX=clang++ CXXFLAGS=-DCRYPTOPP_DISABLE_ASM - INSTALL_COMMAND make install PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -) + URL https://downloads.sourceforge.net/project/cryptopp/cryptopp/5.6.2/cryptopp562.zip + BINARY_DIR cryptopp-prefix/src/cryptopp + CONFIGURE_COMMAND "" + BUILD_COMMAND make CXX=clang++ CXXFLAGS=-DCRYPTOPP_DISABLE_ASM + INSTALL_COMMAND make install PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} + ) +elseif(WIN32) + file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include/cryptopp) + + ExternalProject_Add(cryptopp + SVN_REPOSITORY http://svn.code.sf.net/p/cryptopp/code/trunk/c5 + SVN_REVISION -r "541" + BINARY_DIR cryptopp-prefix/src/cryptopp + CONFIGURE_COMMAND devenv cryptest.sln /upgrade + BUILD_COMMAND devenv cryptest.sln /build release + INSTALL_COMMAND cmd /c cp Win32/DLL_Output/Release/cryptopp.dll ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp Win32/DLL_Output/Release/cryptopp.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp *.h ${ETH_DEPENDENCY_INSTALL_DIR}/include/cryptopp + ) # on Linux, the default Makefile does not work. else() ExternalProject_Add(cryptopp @@ -17,6 +28,6 @@ else() CONFIGURE_COMMAND "" BUILD_COMMAND scons --shared --prefix=${ETH_DEPENDENCY_INSTALL_DIR} INSTALL_COMMAND "" -) + ) endif() From 01167d1b354fe26da5eafed510975b811005ac49 Mon Sep 17 00:00:00 2001 From: debris Date: Wed, 26 Nov 2014 15:42:36 +0100 Subject: [PATCH 033/277] argtable && jsoncpp msbuild --- extdep/CMakeLists.txt | 4 +++- extdep/argtable2.cmake | 12 ++++++++++++ extdep/jsoncpp.cmake | 15 +++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 extdep/argtable2.cmake create mode 100644 extdep/jsoncpp.cmake diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index 7551d2e98..4871d5486 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -9,7 +9,9 @@ set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install/${_system_na file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/lib) file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include) -include(cryptopp.cmake) +include(jsoncpp.cmake) +#include(argtable2.cmake) +#include(cryptopp.cmake) # will be re-eanbled later # include(curl.cmake) #include(json-rpc-cpp.cmake) diff --git a/extdep/argtable2.cmake b/extdep/argtable2.cmake new file mode 100644 index 000000000..3da2f7534 --- /dev/null +++ b/extdep/argtable2.cmake @@ -0,0 +1,12 @@ +if(APPLE) + +elseif(WIN32) +ExternalProject_Add(argtable2 + URL http://sourceforge.net/projects/argtable/files/argtable/argtable-2.13/argtable2-13.tar.gz + BINARY_DIR argtable2-prefix/src/argtable2 + CONFIGURE_COMMAND cmake . + BUILD_COMMAND devenv argtable2.sln /build release + INSTALL_COMMAND cmd /c cp src/Release/argtable2.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp src/argtable2.h ${ETH_DEPENDENCY_INSTALL_DIR}/include +) +else() +endif() diff --git a/extdep/jsoncpp.cmake b/extdep/jsoncpp.cmake new file mode 100644 index 000000000..b3bdef5e2 --- /dev/null +++ b/extdep/jsoncpp.cmake @@ -0,0 +1,15 @@ +if(APPLE) + +elseif(WIN32) + +file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include/jsoncpp) +ExternalProject_Add(jsoncpp + GIT_REPOSITORY https://github.com/open-source-parsers/jsoncpp + GIT_TAG svn-import + BINARY_DIR jsoncpp-prefix/src/jsoncpp + CONFIGURE_COMMAND cmake . + BUILD_COMMAND devenv jsoncpp.sln /build release + INSTALL_COMMAND cmd /c cp lib/Release/jsoncpp.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R include/json ${ETH_DEPENDENCY_INSTALL_DIR}/include/jsoncpp +) +else() +endif() From 8dd7affd09165fe44ea7a625dfe4677923c9349f Mon Sep 17 00:00:00 2001 From: debris Date: Wed, 26 Nov 2014 20:39:16 +0100 Subject: [PATCH 034/277] jsonrpc visual studio windows build! --- extdep/CMakeLists.txt | 10 ++++++---- extdep/argtable2.cmake | 3 ++- extdep/curl.cmake | 29 +++++++++++++++++++++++------ extdep/json-rpc-cpp.cmake | 37 +++++++++++++++++++++++++++++-------- 4 files changed, 60 insertions(+), 19 deletions(-) diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index 4871d5486..5686a0c5d 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -9,11 +9,13 @@ set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install/${_system_na file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/lib) file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include) +include(curl.cmake) include(jsoncpp.cmake) -#include(argtable2.cmake) -#include(cryptopp.cmake) +include(argtable2.cmake) +include(json-rpc-cpp.cmake) +include(cryptopp.cmake) + # will be re-eanbled later # include(curl.cmake) -#include(json-rpc-cpp.cmake) -#include(miniupnpc.cmake) +# include(miniupnpc.cmake) diff --git a/extdep/argtable2.cmake b/extdep/argtable2.cmake index 3da2f7534..88063a40f 100644 --- a/extdep/argtable2.cmake +++ b/extdep/argtable2.cmake @@ -2,7 +2,8 @@ if(APPLE) elseif(WIN32) ExternalProject_Add(argtable2 - URL http://sourceforge.net/projects/argtable/files/argtable/argtable-2.13/argtable2-13.tar.gz + GIT_REPOSITORY https://github.com/debris/argtable.git + GIT_TAG master BINARY_DIR argtable2-prefix/src/argtable2 CONFIGURE_COMMAND cmake . BUILD_COMMAND devenv argtable2.sln /build release diff --git a/extdep/curl.cmake b/extdep/curl.cmake index fa06d7ba0..d4963c1d5 100644 --- a/extdep/curl.cmake +++ b/extdep/curl.cmake @@ -1,13 +1,30 @@ if(APPLE) - set(CONFIG_CMD ./configure --with-darwinssl --prefix=${ETH_DEPENDENCY_INSTALL_DIR} --exec-prefix=${ETH_DEPENDENCY_INSTALL_DIR}) -else() - set (CONFIG_CMD ./configure --prefix=${ETH_DEPENDENCY_INSTALL_DIR} --exec-prefix=${ETH_DEPENDENCY_INSTALL_DIR}) -endif() +ExternalProject_Add(curl + URL http://curl.haxx.se/download/curl-7.38.0.tar.bz2 + BINARY_DIR curl-prefix/src/curl + CONFIGURE_COMMAND ./configure --with-darwinssl --prefix=${ETH_DEPENDENCY_INSTALL_DIR} --exec-prefix=${ETH_DEPENDENCY_INSTALL_DIR} + BUILD_COMMAND make -j 3 + INSTALL_COMMAND make install + ) +elseif(WIN32) +ExternalProject_Add(curl + GIT_REPOSITORY https://github.com/debris/libcurl-7.29 + GIT_TAG master + BINARY_DIR curl-prefix/src/curl + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND cmd /c cp lib/release/libcurl.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R include/curl ${ETH_DEPENDENCY_INSTALL_DIR}/include + ) +else() ExternalProject_Add(curl URL http://curl.haxx.se/download/curl-7.38.0.tar.bz2 BINARY_DIR curl-prefix/src/curl - CONFIGURE_COMMAND ${CONFIG_CMD} + CONFIGURE_COMMAND CONFIG_CMD ./configure --prefix=${ETH_DEPENDENCY_INSTALL_DIR} --exec-prefix=${ETH_DEPENDENCY_INSTALL_DIR} BUILD_COMMAND make -j 3 INSTALL_COMMAND make install -) + ) + +endif() + + diff --git a/extdep/json-rpc-cpp.cmake b/extdep/json-rpc-cpp.cmake index 810fd3a0a..baba1bb19 100644 --- a/extdep/json-rpc-cpp.cmake +++ b/extdep/json-rpc-cpp.cmake @@ -1,20 +1,41 @@ # json-rpc-cpp is under heavy development, not yet stable, and multiplatform builds are not yet available. # DO NOT MESS WITH THESE SETTINGS! IF YOU HAVE TO MAKE CHANGES HERE, CONSULT sven@ethdev.com BEFOREHAND!! -if(APPLE) - set(CONFIG_CMD cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR} -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev .) -else() - set(CONFIG_CMD cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR} -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST .) -endif() +# DO NOT CHANGE ANYTHING HERE! +if(APPLE) +ExternalProject_Add(json-rpc-cpp + # DEPENDS argtable2 jsoncpp + # DEPENDS curl # re-enable later, when we build curl again + GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git + GIT_TAG v0.3.2 + BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp + CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR} -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev . + BUILD_COMMAND make -j 3 + INSTALL_COMMAND make install + ) -# DO NOT CHANGE ANYTHING HERE! +elseif(WIN32) ExternalProject_Add(json-rpc-cpp + DEPENDS argtable2 jsoncpp curl + GIT_REPOSITORY https://github.com/debris/libjson-rpc-cpp.git + GIT_TAG windows + BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp + CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DJSONCPP_INCLUDE_DIRS=${ETH_DEPENDENCY_INSTALL_DIR}/include -DJSONCPP_LIBRARIES=${ETH_DEPENDENCY_INSTALL_DIR}/lib/jsoncpp.lib -DCURL_LIBRARIES=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libcurl.lib -DCURL_INCLUDE_DIRS=${ETH_DEPENDENCY_INSTALL_DIR}/include . + BUILD_COMMAND devenv libjson-rpc-cpp.sln /build release + INSTALL_COMMAND cmd /c cp lib/Release/* ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R src/jsonrpccpp ${ETH_DEPENDENCY_INSTALL_DIR}/include + ) +else() +ExternalProject_Add(json-rpc-cpp + # DEPENDS argtable2 jsoncpp # DEPENDS curl # re-enable later, when we build curl again GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git GIT_TAG v0.3.2 BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp - CONFIGURE_COMMAND ${CONFIG_CMD} + CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR} -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST . BUILD_COMMAND make -j 3 INSTALL_COMMAND make install -) + ) + +endif() + From 941184f6a778833aa914f095caf18962f7002ed4 Mon Sep 17 00:00:00 2001 From: debris Date: Wed, 26 Nov 2014 21:45:09 +0100 Subject: [PATCH 035/277] json-rpc-cpp improved config method --- extdep/json-rpc-cpp.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extdep/json-rpc-cpp.cmake b/extdep/json-rpc-cpp.cmake index baba1bb19..387597615 100644 --- a/extdep/json-rpc-cpp.cmake +++ b/extdep/json-rpc-cpp.cmake @@ -21,7 +21,7 @@ ExternalProject_Add(json-rpc-cpp GIT_REPOSITORY https://github.com/debris/libjson-rpc-cpp.git GIT_TAG windows BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp - CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DJSONCPP_INCLUDE_DIRS=${ETH_DEPENDENCY_INSTALL_DIR}/include -DJSONCPP_LIBRARIES=${ETH_DEPENDENCY_INSTALL_DIR}/lib/jsoncpp.lib -DCURL_LIBRARIES=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libcurl.lib -DCURL_INCLUDE_DIRS=${ETH_DEPENDENCY_INSTALL_DIR}/include . + CONFIGURE_COMMAND cmake -DCMAKE_PREFIX_PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCURL_LIBRARIES=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libcurl.lib . BUILD_COMMAND devenv libjson-rpc-cpp.sln /build release INSTALL_COMMAND cmd /c cp lib/Release/* ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R src/jsonrpccpp ${ETH_DEPENDENCY_INSTALL_DIR}/include ) From cd612bb808774dea7adcb7155dc90c131de2ef57 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 26 Nov 2014 22:05:24 +0100 Subject: [PATCH 036/277] leveldb and snappy for apple build --- extdep/CMakeLists.txt | 3 ++- extdep/leveldb.cmake | 22 ++++++++++++++++++++++ extdep/leveldb_osx.patch | 18 ++++++++++++++++++ extdep/snappy.cmake | 14 ++++++++++++++ 4 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 extdep/leveldb.cmake create mode 100644 extdep/leveldb_osx.patch create mode 100644 extdep/snappy.cmake diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index 5686a0c5d..4a3214d75 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -2,7 +2,6 @@ cmake_minimum_required(VERSION 2.8) include(ExternalProject) - # all dependencies will be installed into this directory, separated by platform string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name) set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install/${_system_name}") @@ -14,6 +13,8 @@ include(jsoncpp.cmake) include(argtable2.cmake) include(json-rpc-cpp.cmake) include(cryptopp.cmake) +include(snappy.cmake) +include(leveldb.cmake) # will be re-eanbled later # include(curl.cmake) diff --git a/extdep/leveldb.cmake b/extdep/leveldb.cmake new file mode 100644 index 000000000..82d9f5a05 --- /dev/null +++ b/extdep/leveldb.cmake @@ -0,0 +1,22 @@ +if(APPLE) +ExternalProject_Add(leveldb + DEPENDS snappy + URL https://leveldb.googlecode.com/files/leveldb-1.15.0.tar.gz + BINARY_DIR leveldb-prefix/src/leveldb + CONFIGURE_COMMAND patch < ${CMAKE_CURRENT_SOURCE_DIR}/leveldb_osx.patch + BUILD_COMMAND export ETH_DEPENDENCY_INSTALL_DIR=${ETH_DEPENDENCY_INSTALL_DIR} && make -j 3 + INSTALL_COMMAND cp -rf include/leveldb ${ETH_DEPENDENCY_INSTALL_DIR}/include/ && mv libleveldb.a ${ETH_DEPENDENCY_INSTALL_DIR}/lib && mv libleveldb.dylib.1.15 ${ETH_DEPENDENCY_INSTALL_DIR}/lib/libleveldb.dylib + ) +elseif(WIN32) +ExternalProject_Add(leveldb + GIT_REPOSITORY https://code.google.com/p/leveldb + GIT_TAG windows + BINARY_DIR leveldb-prefix/src/leveldb + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + ) +else() + +endif() + diff --git a/extdep/leveldb_osx.patch b/extdep/leveldb_osx.patch new file mode 100644 index 000000000..ac9e8f528 --- /dev/null +++ b/extdep/leveldb_osx.patch @@ -0,0 +1,18 @@ +--- Makefile 2014-11-07 00:54:05.000000000 +0100 ++++ MakefilePatch 2014-11-07 00:56:59.000000000 +0100 +@@ -17,11 +17,11 @@ + # this file is generated by the previous line to set build flags and sources + include build_config.mk + +-CFLAGS += -I. -I./include $(PLATFORM_CCFLAGS) $(OPT) +-CXXFLAGS += -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT) ++CFLAGS += -I. -I./include $(PLATFORM_CCFLAGS) $(OPT) ++CXXFLAGS += -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT) -DSNAPPY -I$(ETH_DEPENDENCY_INSTALL_DIR)/include + +-LDFLAGS += $(PLATFORM_LDFLAGS) +-LIBS += $(PLATFORM_LIBS) ++LDFLAGS += $(PLATFORM_LDFLAGS) -L$(ETH_DEPENDENCY_INSTALL_DIR)/lib ++LIBS += $(PLATFORM_LIBS) -lsnappy + + LIBOBJECTS = $(SOURCES:.cc=.o) + MEMENVOBJECTS = $(MEMENV_SOURCES:.cc=.o) diff --git a/extdep/snappy.cmake b/extdep/snappy.cmake new file mode 100644 index 000000000..a15418304 --- /dev/null +++ b/extdep/snappy.cmake @@ -0,0 +1,14 @@ +if(APPLE) +ExternalProject_Add(snappy + URL https://snappy.googlecode.com/files/snappy-1.1.1.tar.gz + BINARY_DIR snappy-prefix/src/snappy + CONFIGURE_COMMAND ./configure --disable-dependency-tracking --prefix=${ETH_DEPENDENCY_INSTALL_DIR} + BUILD_COMMAND "" + INSTALL_COMMAND make install + ) +elseif(WIN32) + +else() + +endif() + From 2dd4f2168a775373ac691a57066ac2da1108d0d2 Mon Sep 17 00:00:00 2001 From: debris Date: Wed, 26 Nov 2014 22:08:42 +0100 Subject: [PATCH 037/277] fixed CMAKE_PREFIX_PATH && MSVC compiler rejection --- cmake/EthCompilerSettings.cmake | 4 +++- cmake/EthDependencies.cmake | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index 6103970c4..8530a54b7 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -10,8 +10,10 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") endif () elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") +elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") else () - message(FATAL_ERROR "Your C++ compiler does not support C++11.") + message(FATAL_ERROR "Your C++ compiler does not support C++11. You have ${CMAKE_CXX_COMPILER_ID}") endif () diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 34d8f18a6..1d6d3418d 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -4,7 +4,7 @@ # by defining this variable, cmake will look for dependencies first in our own repository before looking in system paths like /usr/local/ ... # this must be set to point to the same directory as $ETH_DEPENDENCY_INSTALL_DIR in /extdep directory string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name) -set (CMAKE_FIND_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install/${_system_name}") +set (CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install/${_system_name}") # Dependencies must have a version number + EXACT, to ensure reproducible builds From 859cbb451dea323c7f86fd8ad7af18f440d809c4 Mon Sep 17 00:00:00 2001 From: debris Date: Thu, 27 Nov 2014 10:17:28 +0100 Subject: [PATCH 038/277] leveldb on windows --- cmake/EthDependencies.cmake | 6 ++++++ cmake/FindLevelDB.cmake | 35 +++++++++++++++++++++++++++++++++++ extdep/CMakeLists.txt | 1 - extdep/leveldb.cmake | 6 +++--- 4 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 cmake/FindLevelDB.cmake diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 1d6d3418d..c234cdee4 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -13,6 +13,12 @@ find_package (CryptoPP 5.6.2 EXACT REQUIRED) message(" - CryptoPP header: ${CRYPTOPP_INCLUDE_DIRS}") message(" - CryptoPP lib : ${CRYPTOPP_LIBRARIES}") +# TODO the Jsoncpp package does not yet check for correct version number + +find_package (LevelDB REQUIRED) +message(" - LevelDB header: ${LEVELDB_INCLUDE_DIR}") +message(" - LevelDB lib: ${LEVELDB_LIBRARY}") + # TODO the Jsoncpp package does not yet check for correct version number find_package (Jsoncpp 0.60 EXACT REQUIRED) message(" - Jsoncpp header: ${JSONCPP_INCLUDE_DIRS}") diff --git a/cmake/FindLevelDB.cmake b/cmake/FindLevelDB.cmake new file mode 100644 index 000000000..7daff29f6 --- /dev/null +++ b/cmake/FindLevelDB.cmake @@ -0,0 +1,35 @@ +# Find leveldb +# +# Find the leveldb includes and library +# +# if you nee to add a custom library search path, do it via via CMAKE_FIND_ROOT_PATH +# +# This module defines +# LEVELDB_INCLUDE_DIR, where to find header, etc. +# LEVELDB_LIBRARY, the libraries needed to use leveldb. +# LEVELDB_FOUND, If false, do not try to use leveldb. + +# only look in default directories +find_path( + LEVELDB_INCLUDE_DIR + NAMES leveldb/db.h + DOC "leveldb include dir" +) + +find_library( + LEVELDB_LIBRARY + NAMES leveldb + DOC "leveldb library" +) + +# message (" - leveldb header : ${LEVELDB_INCLUDE_DIR}") +# message (" - leveldb lib : ${LEVELDB_LIBRARY}") + + +# handle the QUIETLY and REQUIRED arguments and set JSON_RPC_CPP_FOUND to TRUE +# if all listed variables are TRUE, hide their existence from configuration view +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(leveldb DEFAULT_MSG + LEVELDB_INCLUDE_DIR LEVELDB_LIBRARY) +mark_as_advanced (LEVELDB_INCLUDE_DIR LEVELDB_LIBRARY) + diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index 4a3214d75..53f3751ed 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -17,6 +17,5 @@ include(snappy.cmake) include(leveldb.cmake) # will be re-eanbled later -# include(curl.cmake) # include(miniupnpc.cmake) diff --git a/extdep/leveldb.cmake b/extdep/leveldb.cmake index 82d9f5a05..8b494457f 100644 --- a/extdep/leveldb.cmake +++ b/extdep/leveldb.cmake @@ -9,12 +9,12 @@ ExternalProject_Add(leveldb ) elseif(WIN32) ExternalProject_Add(leveldb - GIT_REPOSITORY https://code.google.com/p/leveldb - GIT_TAG windows + GIT_REPOSITORY https://github.com/debris/leveldb-win32.git + GIT_TAG master BINARY_DIR leveldb-prefix/src/leveldb CONFIGURE_COMMAND "" BUILD_COMMAND "" - INSTALL_COMMAND "" + INSTALL_COMMAND cmd /c cp lib/LibLevelDB.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib/leveldb.lib && cp -R include/leveldb ${ETH_DEPENDENCY_INSTALL_DIR}/include ) else() From 5d7f374a3882dabc7519fcc60cc0b5d4e9f6bdf4 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 27 Nov 2014 11:38:13 +0100 Subject: [PATCH 039/277] leveldb downloaded locally --- cmake/EthDependenciesDeprecated.cmake | 29 --------------------------- cmake/FindLevelDB.cmake | 6 +++--- eth/CMakeLists.txt | 3 ++- exp/CMakeLists.txt | 3 ++- libdevcore/CMakeLists.txt | 4 ++-- libdevcrypto/CMakeLists.txt | 3 ++- libethcore/CMakeLists.txt | 8 ++++---- libethereum/CMakeLists.txt | 3 ++- libevm/CMakeLists.txt | 3 ++- libp2p/CMakeLists.txt | 3 ++- libweb3jsonrpc/CMakeLists.txt | 3 ++- libwebthree/CMakeLists.txt | 3 ++- libwhisper/CMakeLists.txt | 7 ++++--- neth/CMakeLists.txt | 4 ++-- 14 files changed, 31 insertions(+), 51 deletions(-) diff --git a/cmake/EthDependenciesDeprecated.cmake b/cmake/EthDependenciesDeprecated.cmake index 6876943fa..47ad733e4 100644 --- a/cmake/EthDependenciesDeprecated.cmake +++ b/cmake/EthDependenciesDeprecated.cmake @@ -5,34 +5,8 @@ if("${TARGET_PLATFORM}" STREQUAL "w64") # set(MINIUPNPC_LS /usr/x86_64-w64-mingw32/lib/libminiupnpc.a) - set(LEVELDB_LS leveldb) else() - find_path( LEVELDB_ID leveldb/db.h - /usr/include - /usr/local/include - ) - if ( LEVELDB_ID STREQUAL "LEVELDB_ID-NOTFOUND" ) - message(FATAL_ERROR "Failed to find the LevelDB headers") - else () - message(STATUS "Found LevelDB Headers") - - # Check for accessory dev libraries leveldb and miniupnpc - find_library( LEVELDB_LS NAMES leveldb - PATHS - /usr/lib - /usr/local/lib - /opt/local/lib - /usr/lib/*/ - ) - if ( LEVELDB_LS STREQUAL "LEVELDB_LS-NOTFOUND" ) - message(FATAL_ERROR "Failed to find the LevelDB Library!") - else () - message(STATUS "Found LevelDB Library: ${LEVELDB_LS}") - add_definitions(-DETH_LEVELDB) - endif () - endif () - find_path( PYTHON_ID pyconfig.h ${PYTHON_INCLUDE_DIR} /usr/include/python2.7 @@ -123,9 +97,6 @@ endif() if(MINIUPNPC_ID) include_directories(${MINIUPNPC_ID}) endif() -if(LEVELDB_ID) - include_directories(${LEVELDB_ID}) -endif() if(READLINE_ID) include_directories(${READLINE_ID}) endif() diff --git a/cmake/FindLevelDB.cmake b/cmake/FindLevelDB.cmake index 7daff29f6..770c9e65f 100644 --- a/cmake/FindLevelDB.cmake +++ b/cmake/FindLevelDB.cmake @@ -13,14 +13,14 @@ find_path( LEVELDB_INCLUDE_DIR NAMES leveldb/db.h - DOC "leveldb include dir" -) + DOC "leveldb include dir" + ) find_library( LEVELDB_LIBRARY NAMES leveldb DOC "leveldb library" -) + ) # message (" - leveldb header : ${LEVELDB_INCLUDE_DIR}") # message (" - leveldb lib : ${LEVELDB_LIBRARY}") diff --git a/eth/CMakeLists.txt b/eth/CMakeLists.txt index 2bf2dcc49..934169e1f 100644 --- a/eth/CMakeLists.txt +++ b/eth/CMakeLists.txt @@ -4,6 +4,7 @@ aux_source_directory(. SRC_LIST) include_directories(..) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) +include_directories(${LEVELDB_INCLUDE_DIR}) set(EXECUTABLE eth) @@ -16,7 +17,7 @@ target_link_libraries(${EXECUTABLE} gmp) if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) if(JSON_RPC_CPP_FOUND) target_link_libraries(${EXECUTABLE} web3jsonrpc) endif() diff --git a/exp/CMakeLists.txt b/exp/CMakeLists.txt index 89e5580a4..26ee835d4 100644 --- a/exp/CMakeLists.txt +++ b/exp/CMakeLists.txt @@ -3,6 +3,7 @@ cmake_policy(SET CMP0015 NEW) aux_source_directory(. SRC_LIST) include_directories(..) +include_directories(${LEVELDB_INCLUDE_DIR}) set(EXECUTABLE exp) @@ -14,7 +15,7 @@ target_link_libraries(${EXECUTABLE} gmp) if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) if ("${TARGET_PLATFORM}" STREQUAL "w64") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") diff --git a/libdevcore/CMakeLists.txt b/libdevcore/CMakeLists.txt index c3857a622..939f20593 100644 --- a/libdevcore/CMakeLists.txt +++ b/libdevcore/CMakeLists.txt @@ -7,6 +7,8 @@ endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) +include_directories(..) +include_directories(${LEVELDB_INCLUDE_DIR}) set(EXECUTABLE devcore) @@ -17,8 +19,6 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -include_directories(..) - if("${TARGET_PLATFORM}" STREQUAL "w64") target_link_libraries(${EXECUTABLE} boost_system-mt-s) target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) diff --git a/libdevcrypto/CMakeLists.txt b/libdevcrypto/CMakeLists.txt index 1dd709ffe..7de842fc5 100644 --- a/libdevcrypto/CMakeLists.txt +++ b/libdevcrypto/CMakeLists.txt @@ -13,11 +13,12 @@ endif() include_directories(..) include_directories(${CRYPTOPP_INCLUDE_DIR}) +include_directories(${LEVELDB_INCLUDE_DIR}) target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} secp256k1) target_link_libraries(${EXECUTABLE} gmp) -target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) if("${TARGET_PLATFORM}" STREQUAL "w64") diff --git a/libethcore/CMakeLists.txt b/libethcore/CMakeLists.txt index 49cfc1941..0c50320c3 100644 --- a/libethcore/CMakeLists.txt +++ b/libethcore/CMakeLists.txt @@ -1,6 +1,9 @@ cmake_policy(SET CMP0015 NEW) aux_source_directory(. SRC_LIST) +include_directories(..) +include_directories(${CRYPTOPP_INCLUDE_DIR}) +include_directories(${LEVELDB_INCLUDE_DIR}) set(EXECUTABLE ethcore) @@ -11,14 +14,11 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -include_directories(..) -include_directories(${CRYPTOPP_INCLUDE_DIR}) - target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} secp256k1) target_link_libraries(${EXECUTABLE} gmp) -target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) if("${TARGET_PLATFORM}" STREQUAL "w64") target_link_libraries(${EXECUTABLE} boost_system-mt-s) diff --git a/libethereum/CMakeLists.txt b/libethereum/CMakeLists.txt index 3c00ad6a7..3266a8801 100644 --- a/libethereum/CMakeLists.txt +++ b/libethereum/CMakeLists.txt @@ -14,6 +14,7 @@ else() endif() include_directories(..) +include_directories(${LEVELDB_INCLUDE_DIR}) target_link_libraries(${EXECUTABLE} evm) target_link_libraries(${EXECUTABLE} lll) @@ -25,7 +26,7 @@ target_link_libraries(${EXECUTABLE} secp256k1) if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) target_link_libraries(${EXECUTABLE} gmp) if("${TARGET_PLATFORM}" STREQUAL "w64") diff --git a/libevm/CMakeLists.txt b/libevm/CMakeLists.txt index cddd6b9c9..2812be808 100644 --- a/libevm/CMakeLists.txt +++ b/libevm/CMakeLists.txt @@ -14,6 +14,7 @@ else() endif() include_directories(..) +include_directories(${LEVELDB_INCLUDE_DIR}) target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} devcrypto) @@ -24,7 +25,7 @@ target_link_libraries(${EXECUTABLE} gmp) if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) if("${TARGET_PLATFORM}" STREQUAL "w64") target_link_libraries(${EXECUTABLE} boost_system-mt-s) diff --git a/libp2p/CMakeLists.txt b/libp2p/CMakeLists.txt index f0aeceae5..207d10127 100644 --- a/libp2p/CMakeLists.txt +++ b/libp2p/CMakeLists.txt @@ -14,6 +14,7 @@ else() endif() include_directories(..) +include_directories(${LEVELDB_INCLUDE_DIR}) target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} devcore) @@ -21,7 +22,7 @@ target_link_libraries(${EXECUTABLE} secp256k1) if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) target_link_libraries(${EXECUTABLE} gmp) if("${TARGET_PLATFORM}" STREQUAL "w64") diff --git a/libweb3jsonrpc/CMakeLists.txt b/libweb3jsonrpc/CMakeLists.txt index 7d0695b30..5fb2662e1 100644 --- a/libweb3jsonrpc/CMakeLists.txt +++ b/libweb3jsonrpc/CMakeLists.txt @@ -4,6 +4,7 @@ aux_source_directory(. SRC_LIST) include_directories(..) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) +include_directories(${LEVELDB_INCLUDE_DIR}) link_directories(../libethcore) link_directories(../libwebthree) @@ -24,7 +25,7 @@ target_link_libraries(${EXECUTABLE} serpent) if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_LIBRARIES}) if(READLINE_LS) diff --git a/libwebthree/CMakeLists.txt b/libwebthree/CMakeLists.txt index fbaa43b45..4ec5b2ea4 100644 --- a/libwebthree/CMakeLists.txt +++ b/libwebthree/CMakeLists.txt @@ -14,6 +14,7 @@ else() endif() include_directories(..) +include_directories(${LEVELDB_INCLUDE_DIR}) target_link_libraries(${EXECUTABLE} ethereum) target_link_libraries(${EXECUTABLE} evm) @@ -26,7 +27,7 @@ target_link_libraries(${EXECUTABLE} secp256k1) if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) target_link_libraries(${EXECUTABLE} gmp) if("${TARGET_PLATFORM}" STREQUAL "w64") diff --git a/libwhisper/CMakeLists.txt b/libwhisper/CMakeLists.txt index fdf69650a..62bc5edaf 100644 --- a/libwhisper/CMakeLists.txt +++ b/libwhisper/CMakeLists.txt @@ -4,6 +4,9 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) +include_directories(..) +include_directories(${LEVELDB_INCLUDE_DIR}) + set(EXECUTABLE whisper) file(GLOB HEADERS "*.h") @@ -13,8 +16,6 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -include_directories(..) - target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} devcore) @@ -23,7 +24,7 @@ target_link_libraries(${EXECUTABLE} secp256k1) if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) target_link_libraries(${EXECUTABLE} gmp) if("${TARGET_PLATFORM}" STREQUAL "w64") diff --git a/neth/CMakeLists.txt b/neth/CMakeLists.txt index bae84b5fa..46195a1eb 100644 --- a/neth/CMakeLists.txt +++ b/neth/CMakeLists.txt @@ -3,8 +3,8 @@ cmake_policy(SET CMP0015 NEW) aux_source_directory(. SRC_LIST) include_directories(..) -include_directories(${LEVELDB_ID}) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) +include_directories(${LEVELDB_INCLUDE_DIR}) set(EXECUTABLE neth) @@ -17,7 +17,7 @@ target_link_libraries(${EXECUTABLE} gmp) if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) if(JSON_RPC_CPP_FOUND) target_link_libraries(${EXECUTABLE} web3jsonrpc) endif() From 79f2e52ec6fbe2fcb80822dc1ce708754ec2490c Mon Sep 17 00:00:00 2001 From: sveneh Date: Thu, 27 Nov 2014 20:01:34 +0100 Subject: [PATCH 040/277] use CMAKE_PREFIX_PATH instead of CMAKE_FILE_ROOT_PATH; removed the requirement to use EXACT version numbers for dependencies, cleanup --- cmake/EthDependencies.cmake | 8 ++++---- extdep/CMakeLists.txt | 2 -- extdep/json-rpc-cpp.cmake | 8 ++------ test/CMakeLists.txt | 1 - 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 34d8f18a6..04e57cce7 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -4,22 +4,22 @@ # by defining this variable, cmake will look for dependencies first in our own repository before looking in system paths like /usr/local/ ... # this must be set to point to the same directory as $ETH_DEPENDENCY_INSTALL_DIR in /extdep directory string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name) -set (CMAKE_FIND_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install/${_system_name}") +set (CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install/${_system_name}") -# Dependencies must have a version number + EXACT, to ensure reproducible builds +# Dependencies must have a version number, to ensure reproducible build. The version provided here is the one that is in the extdep repository. If you use system libraries, version numbers may be different. find_package (CryptoPP 5.6.2 EXACT REQUIRED) message(" - CryptoPP header: ${CRYPTOPP_INCLUDE_DIRS}") message(" - CryptoPP lib : ${CRYPTOPP_LIBRARIES}") # TODO the Jsoncpp package does not yet check for correct version number -find_package (Jsoncpp 0.60 EXACT REQUIRED) +find_package (Jsoncpp 0.60 REQUIRED) message(" - Jsoncpp header: ${JSONCPP_INCLUDE_DIRS}") message(" - Jsoncpp lib : ${JSONCPP_LIBRARIES}") # TODO the JsonRpcCpp package does not yet check for correct version number -find_package (JsonRpcCpp 0.3.2 EXACT REQUIRED) +find_package (JsonRpcCpp 0.3.2 REQUIRED) if (${JSON_RPC_CPP_FOUND}) message (" - json-rpc-cpp header: ${JSON_RPC_CPP_INCLUDE_DIRS}") message (" - json-rpc-cpp lib : ${JSON_RPC_CPP_LIBRARIES}") diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index 5ef5e63d5..0e05115dc 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -2,7 +2,6 @@ cmake_minimum_required(VERSION 2.8) include(ExternalProject) - # all dependencies will be installed into this directory, separated by platform string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name) set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install/${_system_name}") @@ -13,4 +12,3 @@ include(cryptopp.cmake) # include(curl.cmake) include(json-rpc-cpp.cmake) #include(miniupnpc.cmake) - diff --git a/extdep/json-rpc-cpp.cmake b/extdep/json-rpc-cpp.cmake index 810fd3a0a..b26af7bb5 100644 --- a/extdep/json-rpc-cpp.cmake +++ b/extdep/json-rpc-cpp.cmake @@ -1,11 +1,7 @@ # json-rpc-cpp is under heavy development, not yet stable, and multiplatform builds are not yet available. # DO NOT MESS WITH THESE SETTINGS! IF YOU HAVE TO MAKE CHANGES HERE, CONSULT sven@ethdev.com BEFOREHAND!! -if(APPLE) - set(CONFIG_CMD cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR} -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev .) -else() - set(CONFIG_CMD cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR} -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST .) -endif() +set(_config_cmd cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR} -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST .) # DO NOT CHANGE ANYTHING HERE! @@ -14,7 +10,7 @@ ExternalProject_Add(json-rpc-cpp GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git GIT_TAG v0.3.2 BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp - CONFIGURE_COMMAND ${CONFIG_CMD} + CONFIGURE_COMMAND ${_config_cmd} BUILD_COMMAND make -j 3 INSTALL_COMMAND make install ) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index fe0408a2b..71b88dbaa 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -19,7 +19,6 @@ target_link_libraries(testeth gmp) target_link_libraries(testeth solidity) target_link_libraries(testeth webthree) -#TODO this on should not be necessary, it should have been brought in from ethcore dependency... target_link_libraries(testeth ${CRYPTOPP_LIBRARIES}) if(JSON_RPC_CPP_FOUND) From 1e7c9739ac6afd1e792452c0a5a4989960a89c9b Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 28 Nov 2014 02:41:38 +0100 Subject: [PATCH 041/277] common changes for windows build --- extdep/CMakeLists.txt | 18 ++++--- extdep/configure.bat | 111 ++++++++++++++++++++++++++++++++++++++++++ extdep/icu.cmake | 18 +++++++ extdep/jom.cmake | 18 +++++++ extdep/qt.cmake | 31 ++++++++++++ extdep/tools.bat | 2 + 6 files changed, 191 insertions(+), 7 deletions(-) create mode 100644 extdep/configure.bat create mode 100644 extdep/icu.cmake create mode 100644 extdep/jom.cmake create mode 100644 extdep/qt.cmake create mode 100644 extdep/tools.bat diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index 53f3751ed..53c1ea3fe 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -7,14 +7,18 @@ string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name) set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install/${_system_name}") file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/lib) file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include) +file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/bin) -include(curl.cmake) -include(jsoncpp.cmake) -include(argtable2.cmake) -include(json-rpc-cpp.cmake) -include(cryptopp.cmake) -include(snappy.cmake) -include(leveldb.cmake) +include(icu.cmake) +include(jom.cmake) +include(qt.cmake) +#include(curl.cmake) +#include(jsoncpp.cmake) +#include(argtable2.cmake) +#include(json-rpc-cpp.cmake) +#include(cryptopp.cmake) +#include(snappy.cmake) +#include(leveldb.cmake) # will be re-eanbled later # include(miniupnpc.cmake) diff --git a/extdep/configure.bat b/extdep/configure.bat new file mode 100644 index 000000000..bd810938a --- /dev/null +++ b/extdep/configure.bat @@ -0,0 +1,111 @@ +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: +:: Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +:: Contact: http://www.qt-project.org/legal +:: +:: This file is part of the tools applications of the Qt Toolkit. +:: +:: $QT_BEGIN_LICENSE:LGPL$ +:: Commercial License Usage +:: Licensees holding valid commercial Qt licenses may use this file in +:: accordance with the commercial license agreement provided with the +:: Software or, alternatively, in accordance with the terms contained in +:: a written agreement between you and Digia. For licensing terms and +:: conditions see http://qt.digia.com/licensing. For further information +:: use the contact form at http://qt.digia.com/contact-us. +:: +:: GNU Lesser General Public License Usage +:: Alternatively, this file may be used under the terms of the GNU Lesser +:: General Public License version 2.1 as published by the Free Software +:: Foundation and appearing in the file LICENSE.LGPL included in the +:: packaging of this file. Please review the following information to +:: ensure the GNU Lesser General Public License version 2.1 requirements +:: will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +:: +:: In addition, as a special exception, Digia gives you certain additional +:: rights. These rights are described in the Digia Qt LGPL Exception +:: version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +:: +:: GNU General Public License Usage +:: Alternatively, this file may be used under the terms of the GNU +:: General Public License version 3.0 as published by the Free Software +:: Foundation and appearing in the file LICENSE.GPL included in the +:: packaging of this file. Please review the following information to +:: ensure the GNU General Public License version 3.0 requirements will be +:: met: http://www.gnu.org/copyleft/gpl.html. +:: +:: +:: $QT_END_LICENSE$ +:: +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +@echo off +set QTSRC=%~dp0 +set QTDIR=%CD% +::if not exist %QTSRC%\.gitignore goto sconf +echo Please wait while bootstrapping configure ... + +for %%C in (cl.exe icl.exe g++.exe perl.exe) do set %%C=%%~$PATH:C + +if "%perl.exe%" == "" ( + echo Perl not found in PATH. Aborting. >&2 + exit /b 1 +) +if not exist mkspecs ( + md mkspecs + if errorlevel 1 goto exit +) +perl %QTSRC%bin\syncqt.pl -minimal -module QtCore -outdir %QTDIR% %QTSRC% +if errorlevel 1 goto exit + +if not exist tools\configure ( + md tools\configure + if errorlevel 1 goto exit +) +cd tools\configure +if errorlevel 1 goto exit + +echo #### Generated by configure.bat - DO NOT EDIT! ####> Makefile +echo/>> Makefile +for /f "tokens=3 usebackq" %%V in (`findstr QT_VERSION_STR %QTSRC%\src\corelib\global\qglobal.h`) do @echo QTVERSION = %%~V>> Makefile +if not "%cl.exe%" == "" ( + echo CXX = cl>>Makefile + echo EXTRA_CXXFLAGS =>>Makefile + rem This must have a trailing space. + echo QTSRC = %QTSRC% >> Makefile + set tmpl=win32 + set make=nmake +) else if not "%icl.exe%" == "" ( + echo CXX = icl>>Makefile + echo EXTRA_CXXFLAGS = /Zc:forScope>>Makefile + rem This must have a trailing space. + echo QTSRC = %QTSRC% >> Makefile + set tmpl=win32 + set make=nmake +) else if not "%g++.exe%" == "" ( + echo CXX = g++>>Makefile + echo EXTRA_CXXFLAGS =>>Makefile + rem This must NOT have a trailing space. + echo QTSRC = %QTSRC:\=/%>> Makefile + set tmpl=mingw + set make=mingw32-make +) else ( + echo No suitable compiler found in PATH. Aborting. >&2 + cd ..\.. + exit /b 1 +) +echo/>> Makefile +type %QTSRC%tools\configure\Makefile.%tmpl% >> Makefile + +%make% +if errorlevel 1 (cd ..\.. & exit /b 1) + +cd ..\.. + +:conf +configure.exe -srcdir %QTSRC% %* +goto exit + +:sconf +%QTSRC%\configure.exe %* +:exit diff --git a/extdep/icu.cmake b/extdep/icu.cmake new file mode 100644 index 000000000..c05862b91 --- /dev/null +++ b/extdep/icu.cmake @@ -0,0 +1,18 @@ +if(APPLE) + +# patch for VS2013 and Windows Qt build +elseif(WIN32) +ExternalProject_Add(icu + GIT_REPOSITORY https://github.com/debris/icu-win32.git + GIT_TAG master + BINARY_DIR icu-prefix/src/icu + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND cmd /c cp lib/*.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R include/unicode ${ETH_DEPENDENCY_INSTALL_DIR}/include + ) + +else() + +endif() + + diff --git a/extdep/jom.cmake b/extdep/jom.cmake new file mode 100644 index 000000000..0370eed8e --- /dev/null +++ b/extdep/jom.cmake @@ -0,0 +1,18 @@ +if(APPLE) + + +elseif(WIN32) +# nmake is not working for qt on windows, do not know why +ExternalProject_Add(jom + URL http://download.qt-project.org/official_releases/jom/jom.zip + BINARY_DIR jom-prefix/src/jom + CONFIGURE_COMMAND "" + BUILD_COMMAND echo %cd% + INSTALL_COMMAND cp jom.exe ${ETH_DEPENDENCY_INSTALL_DIR}/bin + ) + +else() + +endif() + + diff --git a/extdep/qt.cmake b/extdep/qt.cmake new file mode 100644 index 000000000..2f9216f74 --- /dev/null +++ b/extdep/qt.cmake @@ -0,0 +1,31 @@ +if(APPLE) + +elseif(WIN32) +ExternalProject_Add(qt + DEPENDS icu jom + URL http://download.qt-project.org/official_releases/qt/5.2/5.2.1/single/qt-everywhere-opensource-src-5.2.1.tar.gz + BINARY_DIR qt-prefix/src/qt + PATCH_COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/configure.bat qtbase + CONFIGURE_COMMAND configure -prefix ${ETH_DEPENDENCY_INSTALL_DIR} -opensource -confirm-license -release -opengl desktop -platform win32-msvc2013 -icu -I ${ETH_DEPENDENCY_INSTALL_DIR}/include -L ${ETH_DEPENDENCY_INSTALL_DIR}/lib -nomake tests -nomake examples + + BUILD_COMMAND cmd /c ${CMAKE_CURRENT_SOURCE_DIR}/tools.bat && jom + INSTALL_COMMAND cmd /c ${CMAKE_CURRENT_SOURCE_DIR}/tools.bat && jom install + ) + +ExternalProject_Add_Step(qt configure_paths + COMMAND set PATH=${ETH_DEPENDENCY_INSTALL_DIR}/bin;%cd%/gnuwin32/bin;%cd%/qtbase/bin;%PATH% + DEPENDEES patch + DEPENDERS configure + ) + +#ExternalProject_Add_Step(qt configure_visual +# COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tools.bat +# DEPENDEES patch +# DEPENDERS configure +# ) + +else() + +endif() + + diff --git a/extdep/tools.bat b/extdep/tools.bat new file mode 100644 index 000000000..bd588c480 --- /dev/null +++ b/extdep/tools.bat @@ -0,0 +1,2 @@ +rem : import VC environment vars +call "%VS120COMNTOOLS%\..\..\VC\vcvarsall.bat" x86 \ No newline at end of file From bb1f01f9c065d26406107a8d23653b63711189b2 Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 28 Nov 2014 10:38:41 +0100 Subject: [PATCH 042/277] common changes --- extdep/icu.cmake | 2 +- extdep/qt.cmake | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/extdep/icu.cmake b/extdep/icu.cmake index c05862b91..3728280e1 100644 --- a/extdep/icu.cmake +++ b/extdep/icu.cmake @@ -8,7 +8,7 @@ ExternalProject_Add(icu BINARY_DIR icu-prefix/src/icu CONFIGURE_COMMAND "" BUILD_COMMAND "" - INSTALL_COMMAND cmd /c cp lib/*.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R include/unicode ${ETH_DEPENDENCY_INSTALL_DIR}/include + INSTALL_COMMAND cmd /c cp lib/* ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R include/uni ${ETH_DEPENDENCY_INSTALL_DIR}/include && cp bin/* ${ETH_DEPENDENCY_INSTALL_DIR}/bin ) else() diff --git a/extdep/qt.cmake b/extdep/qt.cmake index 2f9216f74..863810d1c 100644 --- a/extdep/qt.cmake +++ b/extdep/qt.cmake @@ -5,11 +5,12 @@ ExternalProject_Add(qt DEPENDS icu jom URL http://download.qt-project.org/official_releases/qt/5.2/5.2.1/single/qt-everywhere-opensource-src-5.2.1.tar.gz BINARY_DIR qt-prefix/src/qt + UPDATE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tools.bat PATCH_COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/configure.bat qtbase CONFIGURE_COMMAND configure -prefix ${ETH_DEPENDENCY_INSTALL_DIR} -opensource -confirm-license -release -opengl desktop -platform win32-msvc2013 -icu -I ${ETH_DEPENDENCY_INSTALL_DIR}/include -L ${ETH_DEPENDENCY_INSTALL_DIR}/lib -nomake tests -nomake examples - - BUILD_COMMAND cmd /c ${CMAKE_CURRENT_SOURCE_DIR}/tools.bat && jom - INSTALL_COMMAND cmd /c ${CMAKE_CURRENT_SOURCE_DIR}/tools.bat && jom install + + BUILD_COMMAND nmake + INSTALL_COMMAND nmake install ) ExternalProject_Add_Step(qt configure_paths From 2424736ffef5cf5bc9b493db092a7837cc882d9c Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Mon, 1 Dec 2014 14:57:10 +0100 Subject: [PATCH 043/277] qt building on mac --- extdep/qt.cmake | 15 ++++++++------- extdep/qt_osx.patch | 11 +++++++++++ 2 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 extdep/qt_osx.patch diff --git a/extdep/qt.cmake b/extdep/qt.cmake index 863810d1c..42f4331ab 100644 --- a/extdep/qt.cmake +++ b/extdep/qt.cmake @@ -1,5 +1,12 @@ if(APPLE) - +ExternalProject_add(qt + URL http://qtmirror.ics.com/pub/qtproject/official_releases/qt/5.3/5.3.2/single/qt-everywhere-opensource-src-5.3.2.tar.gz + BINARY_DIR qt-prefix/src/qt + PATCH_COMMAND patch -d qtmultimedia/src/plugins/avfoundation/mediaplayer < ${CMAKE_CURRENT_SOURCE_DIR}/qt_osx.patch + CONFIGURE_COMMAND ./configure -prefix ${ETH_DEPENDENCY_INSTALL_DIR} -system-zlib -qt-libpng -qt-libjpeg -confirm-license -opensource -nomake tests -release -nomake examples -no-xcb -arch x86_64 + BUILD_COMMAND make + INSTALL_COMMAND make install + ) elseif(WIN32) ExternalProject_Add(qt DEPENDS icu jom @@ -19,12 +26,6 @@ ExternalProject_Add_Step(qt configure_paths DEPENDERS configure ) -#ExternalProject_Add_Step(qt configure_visual -# COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tools.bat -# DEPENDEES patch -# DEPENDERS configure -# ) - else() endif() diff --git a/extdep/qt_osx.patch b/extdep/qt_osx.patch new file mode 100644 index 000000000..7900f6094 --- /dev/null +++ b/extdep/qt_osx.patch @@ -0,0 +1,11 @@ +--- avfmediaplayersession.mm 2014-09-11 12:48:26.000000000 +0200 ++++ avfmediaplayersessionPatch.mm 2014-12-01 12:53:14.000000000 +0100 +@@ -295,7 +295,7 @@ + //AVPlayerItem "status" property value observer. + if (context == AVFMediaPlayerSessionObserverStatusObservationContext) + { +- AVPlayerStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue]; ++ AVPlayerStatus status = (AVPlayerStatus)[[change objectForKey:NSKeyValueChangeNewKey] integerValue]; + switch (status) + { + //Indicates that the status of the player is not yet known because From 12485073f0b631d8e7cefda5a964ad28dbc9f384 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Mon, 1 Dec 2014 14:59:36 +0100 Subject: [PATCH 044/277] common changes --- extdep/CMakeLists.txt | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index 0cb2851d4..975207c8b 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -12,16 +12,13 @@ file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/bin) include(icu.cmake) include(jom.cmake) include(qt.cmake) -#include(curl.cmake) -#include(jsoncpp.cmake) -#include(argtable2.cmake) -#include(json-rpc-cpp.cmake) -#include(cryptopp.cmake) -#include(snappy.cmake) -#include(leveldb.cmake) +include(curl.cmake) +include(jsoncpp.cmake) +include(argtable2.cmake) +include(json-rpc-cpp.cmake) +include(cryptopp.cmake) +include(snappy.cmake) +include(leveldb.cmake) # will be re-eanbled later # include(miniupnpc.cmake) -# include(curl.cmake) - -#include(miniupnpc.cmake) From 652d08ab437e6c424b3ec13d68b40140d5d32d91 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Mon, 1 Dec 2014 18:08:22 +0100 Subject: [PATCH 045/277] cleaning cmakes in progress --- alethzero/CMakeLists.txt | 71 ++++++++++------------------ cmake/EthDependencies.cmake | 14 ++++++ libqethereum/CMakeLists.txt | 94 +------------------------------------ third/CMakeLists.txt | 14 ++---- 4 files changed, 44 insertions(+), 149 deletions(-) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index 170f026a7..8d31f173c 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -1,34 +1,16 @@ +cmake_policy(SET CMP0015 OLD) + set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) include_directories(..) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) -if (APPLE) - # Add homebrew path for qt5 - set(CMAKE_PREFIX_PATH /usr/local/opt/qt5) - include_directories(/usr/local/opt/qt5/include /usr/local/include) -elseif ("${TARGET_PLATFORM}" STREQUAL "w64") - set(SRC_LIST ${SRC_LIST} ../windows/qt_plugin_import.cpp) - include_directories(/usr/x86_64-w64-mingw32/include /usr/x86_64-w64-mingw32/include/QtCore /usr/x86_64-w64-mingw32/include/QtGui /usr/x86_64-w64-mingw32/include/QtQuick /usr/x86_64-w64-mingw32/include/QtQml /usr/x86_64-w64-mingw32/include/QtNetwork /usr/x86_64-w64-mingw32/include/QtWidgets /usr/x86_64-w64-mingw32/include/QtWebKit /usr/x86_64-w64-mingw32/include/QtWebKitWidgets) -elseif (UNIX) - set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ";$ENV{QTDIR}/lib/cmake") -endif () - -find_package(Qt5Core REQUIRED) -find_package(Qt5Gui REQUIRED) -find_package(Qt5Quick REQUIRED) -find_package(Qt5Qml REQUIRED) -find_package(Qt5Network REQUIRED) -find_package(Qt5Widgets REQUIRED) -find_package(Qt5WebKit REQUIRED) -find_package(Qt5WebKitWidgets REQUIRED) - qt5_wrap_ui(ui_Main.h Main.ui) # Set name of binary and add_executable() file(GLOB HEADERS "*.h") if (APPLE) - set(EXECUTEABLE AlethZero) + set(EXECUTABLE AlethZero) set(BIN_INSTALL_DIR ".") set(DOC_INSTALL_DIR ".") @@ -39,34 +21,34 @@ if (APPLE) set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}") set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}") set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}") - set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTEABLE}) + set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTABLE}) set(MACOSX_BUNDLE_ICON_FILE alethzero) include(BundleUtilities) - add_executable(${EXECUTEABLE} MACOSX_BUNDLE alethzero.icns Main.ui ${SRC_LIST} ${HEADERS}) - set_target_properties(${EXECUTEABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") - SET_SOURCE_FILES_PROPERTIES(${EXECUTEABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) + add_executable(${EXECUTABLE} MACOSX_BUNDLE alethzero.icns Main.ui ${SRC_LIST} ${HEADERS}) + set_target_properties(${EXECUTABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") + SET_SOURCE_FILES_PROPERTIES(${EXECUTABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) SET_SOURCE_FILES_PROPERTIES(${MACOSX_BUNDLE_ICON_FILE}.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") - else () - set(EXECUTEABLE alethzero) - add_executable(${EXECUTEABLE} Main.ui ${SRC_LIST} ${HEADERS}) + set(EXECUTABLE alethzero) + add_executable(${EXECUTABLE} Main.ui ${SRC_LIST} ${HEADERS}) endif () -qt5_use_modules(${EXECUTEABLE} Core)# Gui Widgets Network WebKit WebKitWidgets) -target_link_libraries(${EXECUTEABLE} webthree qethereum ethereum evm ethcore devcrypto secp256k1 gmp serpent lll solidity evmcore devcore web3jsonrpc jsqrc ${JSONCPP_LIBRARIES}) +qt5_use_modules(${EXECUTABLE} Core) +target_link_libraries(${EXECUTABLE} webthree qethereum ethereum evm ethcore devcrypto secp256k1 gmp serpent lll solidity evmcore devcore web3jsonrpc jsqrc ${JSONCPP_LIBRARIES}) if (APPLE) # First have qt5 install plugins and frameworks - add_custom_command(TARGET ${EXECUTEABLE} POST_BUILD - COMMAND /usr/local/opt/qt5/bin/macdeployqt ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTEABLE}.app + # replace CMAKE_PREFIX_PATH with QT_PATH ? + add_custom_command(TARGET ${EXECUTABLE} POST_BUILD + COMMAND ${CMAKE_PREFIX_PATH}/bin/macdeployqt ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) # This tool and next will inspect linked libraries in order to determine which dependencies are required if (${CMAKE_CFG_INTDIR} STREQUAL ".") - set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTEABLE}.app") + set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE}.app") else () - set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/\$ENV{CONFIGURATION}/${EXECUTEABLE}.app") + set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/\$ENV{CONFIGURATION}/${EXECUTABLE}.app") endif () install(CODE " include(BundleUtilities) @@ -83,20 +65,17 @@ if (APPLE) elseif ("${TARGET_PLATFORM}" STREQUAL "w64") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-keep-inline-dllexport -static-libgcc -static-libstdc++ -static") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-s -Wl,-subsystem,windows -mthreads -L/usr/x86_64-w64-mingw32/plugins/platforms") - target_link_libraries(${EXECUTEABLE} gcc) - target_link_libraries(${EXECUTEABLE} mingw32 qtmain mswsock iphlpapi qwindows shlwapi Qt5PlatformSupport opengl32 gdi32 comdlg32 oleaut32 imm32 winmm ole32 uuid ws2_32) - target_link_libraries(${EXECUTEABLE} boost_system-mt-s) - target_link_libraries(${EXECUTEABLE} boost_filesystem-mt-s) - target_link_libraries(${EXECUTEABLE} boost_thread_win32-mt-s) - target_link_libraries(${EXECUTEABLE} crypt32) - target_link_libraries(${EXECUTEABLE} Qt5PlatformSupport) + target_link_libraries(${EXECUTABLE} gcc) + target_link_libraries(${EXECUTABLE} mingw32 qtmain mswsock iphlpapi qwindows shlwapi Qt5PlatformSupport opengl32 gdi32 comdlg32 oleaut32 imm32 winmm ole32 uuid ws2_32) + target_link_libraries(${EXECUTABLE} boost_system-mt-s) + target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) + target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) + target_link_libraries(${EXECUTABLE} crypt32) + target_link_libraries(${EXECUTABLE} Qt5PlatformSupport) set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) elseif (UNIX) + else () - target_link_libraries(${EXECUTEABLE} boost_system) - target_link_libraries(${EXECUTEABLE} boost_filesystem) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTEABLE} ${CMAKE_THREAD_LIBS_INIT}) - install( TARGETS ${EXECUTEABLE} RUNTIME DESTINATION bin ) + message(STATUS "platform not supported") endif () diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 854344819..7b938ae5f 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -29,3 +29,17 @@ if (${JSON_RPC_CPP_FOUND}) message (" - json-rpc-cpp lib : ${JSON_RPC_CPP_LIBRARIES}") add_definitions(-DETH_JSONRPC) endif() + +find_package (QT5Core REQUIRED) +find_package (QT5Gui REQUIRED) +find_package (Qt5Quick REQUIRED) +find_package (Qt5Qml REQUIRED) +find_package (Qt5Network REQUIRED) +find_package (Qt5Widgets REQUIRED) +find_package (Qt5WebKit REQUIRED) +find_package (Qt5WebKitWidgets REQUIRED) + + + + + diff --git a/libqethereum/CMakeLists.txt b/libqethereum/CMakeLists.txt index 7b2ab6ab6..c58c30426 100644 --- a/libqethereum/CMakeLists.txt +++ b/libqethereum/CMakeLists.txt @@ -1,111 +1,21 @@ -cmake_policy(SET CMP0015 NEW) - -if ("${TARGET_PLATFORM}" STREQUAL "w64") - cmake_policy(SET CMP0020 NEW) -endif () - +cmake_policy(SET CMP0015 OLD) set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) include_directories(..) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) -link_directories(../libethereum) - -# Find Qt5 for Apple and update src_list for windows -if (APPLE) - # homebrew defaults to qt4 and installs qt5 as 'keg-only' - # which places it into /usr/local/opt insteadof /usr/local. - - set(CMAKE_PREFIX_PATH /usr/local/opt/qt5) - include_directories(/usr/local/opt/qt5/include /usr/local/include) -elseif ("${TARGET_PLATFORM}" STREQUAL "w64") - set(SRC_LIST ${SRC_LIST} ../windows/qt_plugin_import.cpp) -elseif (UNIX) - set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ";$ENV{QTDIR}/lib/cmake") -endif () - -find_package(Qt5Gui REQUIRED) -find_package(Qt5Quick REQUIRED) -find_package(Qt5Qml REQUIRED) -find_package(Qt5Network REQUIRED) -find_package(Qt5Widgets REQUIRED) -find_package(Qt5WebKit REQUIRED) -find_package(Qt5WebKitWidgets REQUIRED) set(EXECUTABLE qethereum) -# Set name of binary and add_executable() -if (APPLE) - set(CMAKE_INSTALL_PREFIX ./) - set(BIN_INSTALL_DIR ".") - set(DOC_INSTALL_DIR ".") - - set(PROJECT_VERSION "${ETH_VERSION}") - set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_NAME} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}") - set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}") - set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}") - set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTABLE}) - include(BundleUtilities) -endif () file(GLOB HEADERS "*.h") + if(ETH_STATIC) add_library(${EXECUTABLE} STATIC ${RESOURCE_ADDED} ${SRC_LIST} ${HEADERS}) else() add_library(${EXECUTABLE} SHARED ${RESOURCE_ADDED} ${SRC_LIST} ${HEADERS}) endif() -include_directories(/) qt5_use_modules(${EXECUTABLE} Core Gui WebKit WebKitWidgets Widgets Network Quick Qml) target_link_libraries(${EXECUTABLE} ethereum secp256k1 ${JSON_RPC_CPP_LIBRARIES}) -if (APPLE) - if (${ADDFRAMEWORKS}) - set_target_properties(${EXECUTABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") - endif () - - SET_SOURCE_FILES_PROPERTIES(${EXECUTABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) - - # This is a workaround for when the build-type defaults to Debug, and when a multi-config generator like xcode is used, where the type - # will not be set but defaults to release. - set(generator_lowercase "${CMAKE_GENERATOR}") - string(TOLOWER "${CMAKE_GENERATOR}" generator_lowercase) - if ("${generator_lowercase}" STREQUAL "xcode") - # TODO: Not sure how to resolve this. Possibly \${TARGET_BUILD_DIR} - set(binary_build_dir "${CMAKE_CURRENT_BINARY_DIR}/Debug") - else () - set(binary_build_dir "${CMAKE_CURRENT_BINARY_DIR}") - endif () - - set(APPS ${binary_build_dir}/${EXECUTABLE}) - - if (${ADDFRAMEWORKS}) - add_custom_target(addframeworks ALL - COMMAND /usr/local/opt/qt5/bin/macdeployqt ${binary_build_dir}/${EXECUTABLE} - WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - DEPENDS ${PROJECT_NAME} - ) - endif () - -elseif ("${TARGET_PLATFORM}" STREQUAL "w64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-keep-inline-dllexport -static-libgcc -static-libstdc++ -static") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-s -Wl,-subsystem,windows -mthreads -L/usr/x86_64-w64-mingw32/plugins/platforms") - target_link_libraries(${EXECUTABLE} gcc) - target_link_libraries(${EXECUTABLE} mingw32 qtmain mswsock iphlpapi qwindows shlwapi Qt5PlatformSupport gdi32 comdlg32 oleaut32 imm32 winmm ole32 uuid ws2_32) - target_link_libraries(${EXECUTABLE} boost_system-mt-s) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) - target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) - target_link_libraries(${EXECUTABLE} Qt5PlatformSupport) - set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) -elseif (UNIX) -else () - target_link_libraries(${EXECUTABLE} boost_system) - target_link_libraries(${EXECUTABLE} boost_filesystem) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) - install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) -endif () - diff --git a/third/CMakeLists.txt b/third/CMakeLists.txt index 3583bf6fa..383985318 100644 --- a/third/CMakeLists.txt +++ b/third/CMakeLists.txt @@ -5,8 +5,8 @@ include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) if (APPLE) # Add homebrew path for qt5 - set(CMAKE_PREFIX_PATH /usr/local/opt/qt5) - include_directories(/usr/local/opt/qt5/include /usr/local/include) + #set(CMAKE_PREFIX_PATH /usr/local/opt/qt5) + #include_directories(/usr/local/opt/qt5/include /usr/local/include) elseif ("${TARGET_PLATFORM}" STREQUAL "w64") set(SRC_LIST ${SRC_LIST} ../windows/qt_plugin_import.cpp) include_directories(/usr/x86_64-w64-mingw32/include /usr/x86_64-w64-mingw32/include/QtCore /usr/x86_64-w64-mingw32/include/QtGui /usr/x86_64-w64-mingw32/include/QtQuick /usr/x86_64-w64-mingw32/include/QtQml /usr/x86_64-w64-mingw32/include/QtNetwork /usr/x86_64-w64-mingw32/include/QtWidgets /usr/x86_64-w64-mingw32/include/QtWebKit /usr/x86_64-w64-mingw32/include/QtWebKitWidgets) @@ -14,14 +14,6 @@ elseif (UNIX) set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ";$ENV{QTDIR}/lib/cmake") endif () -find_package(Qt5Core REQUIRED) -find_package(Qt5Gui REQUIRED) -find_package(Qt5Quick REQUIRED) -find_package(Qt5Qml REQUIRED) -find_package(Qt5Network REQUIRED) -find_package(Qt5Widgets REQUIRED) -find_package(Qt5WebKit REQUIRED) -find_package(Qt5WebKitWidgets REQUIRED) qt5_wrap_ui(ui_Main.h Main.ui) @@ -59,7 +51,7 @@ target_link_libraries(${EXECUTEABLE} webthree qethereum ethereum evm ethcore sec if (APPLE) # First have qt5 install plugins and frameworks add_custom_command(TARGET ${EXECUTEABLE} POST_BUILD - COMMAND /usr/local/opt/qt5/bin/macdeployqt ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTEABLE}.app + COMMAND ${CMAKE_PREFIX_PATH}/bin/macdeployqt ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTEABLE}.app WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) # This tool and next will inspect linked libraries in order to determine which dependencies are required From 27a0ad1e766826e03446f6f35841c4dc60b601cb Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Mon, 1 Dec 2014 19:20:52 +0100 Subject: [PATCH 046/277] cmake cleanup cd. --- alethzero/CMakeLists.txt | 19 ++++++++++++-- eth/CMakeLists.txt | 25 +++++++++++-------- exp/CMakeLists.txt | 35 +++++++------------------- libdevcore/CMakeLists.txt | 26 ++++++------------- libdevcore/CommonData.cpp | 3 ++- libdevcrypto/CMakeLists.txt | 33 +++++------------------- libweb3jsonrpc/CMakeLists.txt | 47 ++++++++++------------------------- 7 files changed, 69 insertions(+), 119 deletions(-) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index 8d31f173c..0f2da0df0 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_policy(SET CMP0015 OLD) +#set(CMAKE_AUTOMOC OFF) set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) @@ -35,7 +36,22 @@ else () endif () qt5_use_modules(${EXECUTABLE} Core) -target_link_libraries(${EXECUTABLE} webthree qethereum ethereum evm ethcore devcrypto secp256k1 gmp serpent lll solidity evmcore devcore web3jsonrpc jsqrc ${JSONCPP_LIBRARIES}) +target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES}) +target_link_libraries(${EXECUTABLE} webthree) +target_link_libraries(${EXECUTABLE} qethereum) +target_link_libraries(${EXECUTABLE} ethereum) +target_link_libraries(${EXECUTABLE} evm) +target_link_libraries(${EXECUTABLE} ethcore) +target_link_libraries(${EXECUTABLE} devcrypto) +target_link_libraries(${EXECUTABLE} secp256k1) +target_link_libraries(${EXECUTABLE} gmp) +target_link_libraries(${EXECUTABLE} serpent) +target_link_libraries(${EXECUTABLE} lll) +target_link_libraries(${EXECUTABLE} solidity) +target_link_libraries(${EXECUTABLE} evmcore) +target_link_libraries(${EXECUTABLE} devcore) +target_link_libraries(${EXECUTABLE} web3jsonrpc) +target_link_libraries(${EXECUTABLE} jsqrc) if (APPLE) # First have qt5 install plugins and frameworks @@ -74,7 +90,6 @@ elseif ("${TARGET_PLATFORM}" STREQUAL "w64") target_link_libraries(${EXECUTABLE} Qt5PlatformSupport) set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) elseif (UNIX) - else () message(STATUS "platform not supported") endif () diff --git a/eth/CMakeLists.txt b/eth/CMakeLists.txt index 934169e1f..5ccac182b 100644 --- a/eth/CMakeLists.txt +++ b/eth/CMakeLists.txt @@ -1,30 +1,35 @@ -cmake_policy(SET CMP0015 NEW) +cmake_policy(SET CMP0015 OLD) +set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) -include_directories(..) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) include_directories(${LEVELDB_INCLUDE_DIR}) +include_directories(..) set(EXECUTABLE eth) file(GLOB HEADERS "*.h") + add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) -target_link_libraries(${EXECUTABLE} webthree) -target_link_libraries(${EXECUTABLE} secp256k1) -target_link_libraries(${EXECUTABLE} gmp) if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) + if(JSON_RPC_CPP_FOUND) target_link_libraries(${EXECUTABLE} web3jsonrpc) endif() + if(READLINE_LS) target_link_libraries(${EXECUTABLE} ${READLINE_LS}) endif() +target_link_libraries(${EXECUTABLE} webthree) +target_link_libraries(${EXECUTABLE} secp256k1) +target_link_libraries(${EXECUTABLE} gmp) + if ("${TARGET_PLATFORM}" STREQUAL "w64") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") target_link_libraries(${EXECUTABLE} boost_system-mt-s) @@ -39,10 +44,10 @@ if ("${TARGET_PLATFORM}" STREQUAL "w64") set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) elseif (UNIX) else () - target_link_libraries(${EXECUTABLE} boost_system) - target_link_libraries(${EXECUTABLE} boost_filesystem) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) + #target_link_libraries(${EXECUTABLE} boost_system) + #target_link_libraries(${EXECUTABLE} boost_filesystem) + #find_package(Threads REQUIRED) + #target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) endif () install( TARGETS ${EXECUTABLE} DESTINATION bin ) diff --git a/exp/CMakeLists.txt b/exp/CMakeLists.txt index 26ee835d4..6fcea5341 100644 --- a/exp/CMakeLists.txt +++ b/exp/CMakeLists.txt @@ -1,41 +1,24 @@ cmake_policy(SET CMP0015 NEW) +set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) -include_directories(..) include_directories(${LEVELDB_INCLUDE_DIR}) +include_directories(..) set(EXECUTABLE exp) add_executable(${EXECUTABLE} ${SRC_LIST}) -target_link_libraries(${EXECUTABLE} ethereum) -target_link_libraries(${EXECUTABLE} p2p) -target_link_libraries(${EXECUTABLE} gmp) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) + if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) -if ("${TARGET_PLATFORM}" STREQUAL "w64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") - target_link_libraries(${EXECUTABLE} gcc) - target_link_libraries(${EXECUTABLE} gdi32) - target_link_libraries(${EXECUTABLE} ws2_32) - target_link_libraries(${EXECUTABLE} mswsock) - target_link_libraries(${EXECUTABLE} shlwapi) - target_link_libraries(${EXECUTABLE} iphlpapi) - target_link_libraries(${EXECUTABLE} boost_system-mt-s) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) - target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) - set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) -elseif (UNIX) -else () - target_link_libraries(${EXECUTABLE} boost_system) - target_link_libraries(${EXECUTABLE} boost_filesystem) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -endif () - -install( TARGETS ${EXECUTABLE} DESTINATION bin ) +target_link_libraries(${EXECUTABLE} ethereum) +target_link_libraries(${EXECUTABLE} p2p) +target_link_libraries(${EXECUTABLE} gmp) + +install( TARGETS ${EXECUTABLE} DESTINATION bin) diff --git a/libdevcore/CMakeLists.txt b/libdevcore/CMakeLists.txt index 939f20593..3ff0733b4 100644 --- a/libdevcore/CMakeLists.txt +++ b/libdevcore/CMakeLists.txt @@ -1,32 +1,24 @@ -cmake_policy(SET CMP0015 NEW) - -if (CMAKE_MAJOR_VERSION GREATER 1 AND CMAKE_MINOR_VERSION GREATER 7 AND CMAKE_PATCH_VERSION GREATER 11) - cmake_policy(SET CMP0022 NEW) -endif() +cmake_policy(SET CMP0015 OLD) +set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) -include_directories(..) + include_directories(${LEVELDB_INCLUDE_DIR}) +include_directories(..) set(EXECUTABLE devcore) file(GLOB HEADERS "*.h") + if(ETH_STATIC) add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS}) else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -if("${TARGET_PLATFORM}" STREQUAL "w64") - target_link_libraries(${EXECUTABLE} boost_system-mt-s) - target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) - target_link_libraries(${EXECUTABLE} iphlpapi) - target_link_libraries(${EXECUTABLE} ws2_32) - target_link_libraries(${EXECUTABLE} mswsock) - target_link_libraries(${EXECUTABLE} shlwapi) -elseif (APPLE) +if (APPLE) # Latest mavericks boost libraries only come with -mt target_link_libraries(${EXECUTABLE} boost_system-mt) target_link_libraries(${EXECUTABLE} boost_filesystem-mt) @@ -38,11 +30,7 @@ elseif (UNIX) target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY} ${Boost_SYSTEM_LIBRARY}) find_package(Threads REQUIRED) target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -else () - target_link_libraries(${EXECUTABLE} boost_thread) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -endif () +endif() install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/libdevcore/CommonData.cpp b/libdevcore/CommonData.cpp index bd7841402..d34b565eb 100644 --- a/libdevcore/CommonData.cpp +++ b/libdevcore/CommonData.cpp @@ -23,7 +23,8 @@ #include #include "Exceptions.h" -#include +#include "Log.h" + using namespace std; using namespace dev; diff --git a/libdevcrypto/CMakeLists.txt b/libdevcrypto/CMakeLists.txt index 7de842fc5..423a9ccc6 100644 --- a/libdevcrypto/CMakeLists.txt +++ b/libdevcrypto/CMakeLists.txt @@ -1,4 +1,5 @@ -cmake_policy(SET CMP0015 NEW) +cmake_policy(SET CMP0015 OLD) +set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) @@ -11,44 +12,22 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -include_directories(..) include_directories(${CRYPTOPP_INCLUDE_DIR}) include_directories(${LEVELDB_INCLUDE_DIR}) +include_directories(..) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} secp256k1) target_link_libraries(${EXECUTABLE} gmp) -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) -target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) -if("${TARGET_PLATFORM}" STREQUAL "w64") - target_link_libraries(${EXECUTABLE} boost_system-mt-s) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) - target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) - target_link_libraries(${EXECUTABLE} iphlpapi) - target_link_libraries(${EXECUTABLE} ws2_32) - target_link_libraries(${EXECUTABLE} mswsock) - target_link_libraries(${EXECUTABLE} shlwapi) -elseif (APPLE) +if (APPLE) # Latest mavericks boost libraries only come with -mt - target_link_libraries(${EXECUTABLE} boost_system-mt) target_link_libraries(${EXECUTABLE} boost_filesystem-mt) - target_link_libraries(${EXECUTABLE} boost_thread-mt) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) elseif (UNIX) find_package(Boost 1.53 REQUIRED COMPONENTS filesystem) - target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY}) target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -else () - target_link_libraries(${EXECUTABLE} boost_system) - target_link_libraries(${EXECUTABLE} boost_filesystem) - target_link_libraries(${EXECUTABLE} boost_thread) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) endif () install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) diff --git a/libweb3jsonrpc/CMakeLists.txt b/libweb3jsonrpc/CMakeLists.txt index 5fb2662e1..97130718e 100644 --- a/libweb3jsonrpc/CMakeLists.txt +++ b/libweb3jsonrpc/CMakeLists.txt @@ -1,56 +1,35 @@ -cmake_policy(SET CMP0015 NEW) +cmake_policy(SET CMP0015 OLD) +set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) -include_directories(..) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) include_directories(${LEVELDB_INCLUDE_DIR}) -link_directories(../libethcore) -link_directories(../libwebthree) +include_directories(..) set(EXECUTABLE web3jsonrpc) + file(GLOB HEADERS "*.h") -if(ETH_STATIC) +if (ETH_STATIC) add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS}) else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -target_link_libraries(${EXECUTABLE} webthree) -target_link_libraries(${EXECUTABLE} secp256k1) -target_link_libraries(${EXECUTABLE} gmp) -target_link_libraries(${EXECUTABLE} solidity) -target_link_libraries(${EXECUTABLE} serpent) -if(MINIUPNPC_LS) - target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) -endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_LIBRARIES}) -if(READLINE_LS) -target_link_libraries(${EXECUTABLE} ${READLINE_LS}) + +if (MINIUPNPC_LS) + target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() -if ("${TARGET_PLATFORM}" STREQUAL "w64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") - target_link_libraries(${EXECUTABLE} boost_system-mt-s) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) - target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) - target_link_libraries(${EXECUTABLE} gcc) - target_link_libraries(${EXECUTABLE} gdi32) - target_link_libraries(${EXECUTABLE} ws2_32) - target_link_libraries(${EXECUTABLE} mswsock) - target_link_libraries(${EXECUTABLE} shlwapi) - target_link_libraries(${EXECUTABLE} iphlpapi) - set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) -elseif (UNIX) -else () - target_link_libraries(${EXECUTABLE} boost_system) - target_link_libraries(${EXECUTABLE} boost_filesystem) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -endif () +target_link_libraries(${EXECUTABLE} webthree) +target_link_libraries(${EXECUTABLE} secp256k1) +target_link_libraries(${EXECUTABLE} gmp) +target_link_libraries(${EXECUTABLE} solidity) +target_link_libraries(${EXECUTABLE} serpent) install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) From 110964ffe2e7183c42e1feadddd47ee876e5d287 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Mon, 1 Dec 2014 20:24:20 +0100 Subject: [PATCH 047/277] common changes in cleanup --- alethzero/CMakeLists.txt | 1 + libethcore/CMakeLists.txt | 38 +++++++++---------------------------- libethereum/CMakeLists.txt | 36 ++++++++++++----------------------- libethereumx/CMakeLists.txt | 34 ++++++++++----------------------- libevm/CMakeLists.txt | 29 +++++++++------------------- libqethereum/CMakeLists.txt | 2 ++ libserpent/CMakeLists.txt | 1 - 7 files changed, 43 insertions(+), 98 deletions(-) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index 0f2da0df0..b7c41cda3 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -37,6 +37,7 @@ endif () qt5_use_modules(${EXECUTABLE} Core) target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) target_link_libraries(${EXECUTABLE} webthree) target_link_libraries(${EXECUTABLE} qethereum) target_link_libraries(${EXECUTABLE} ethereum) diff --git a/libethcore/CMakeLists.txt b/libethcore/CMakeLists.txt index 0c50320c3..99ae26776 100644 --- a/libethcore/CMakeLists.txt +++ b/libethcore/CMakeLists.txt @@ -1,54 +1,34 @@ cmake_policy(SET CMP0015 NEW) +set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) -include_directories(..) + include_directories(${CRYPTOPP_INCLUDE_DIR}) include_directories(${LEVELDB_INCLUDE_DIR}) +include_directories(..) set(EXECUTABLE ethcore) file(GLOB HEADERS "*.h") + if(ETH_STATIC) add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS}) else() - add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) + add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} secp256k1) target_link_libraries(${EXECUTABLE} gmp) -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) -if("${TARGET_PLATFORM}" STREQUAL "w64") - target_link_libraries(${EXECUTABLE} boost_system-mt-s) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) - target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) - target_link_libraries(${EXECUTABLE} iphlpapi) - target_link_libraries(${EXECUTABLE} ws2_32) - target_link_libraries(${EXECUTABLE} mswsock) - target_link_libraries(${EXECUTABLE} shlwapi) -elseif (APPLE) - # Latest mavericks boost libraries only come with -mt +if (APPLE) target_link_libraries(${EXECUTABLE} boost_system-mt) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt) - target_link_libraries(${EXECUTABLE} boost_thread-mt) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) elseif (UNIX) - find_package(Boost 1.53 REQUIRED COMPONENTS filesystem) + find_package(Boost 1.53 REQUIRED COMPONENTS system) target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -else () - target_link_libraries(${EXECUTABLE} boost_system) - target_link_libraries(${EXECUTABLE} boost_filesystem) - target_link_libraries(${EXECUTABLE} boost_thread) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -endif () +endif() install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/libethereum/CMakeLists.txt b/libethereum/CMakeLists.txt index 3266a8801..ce1b830f5 100644 --- a/libethereum/CMakeLists.txt +++ b/libethereum/CMakeLists.txt @@ -1,4 +1,5 @@ -cmake_policy(SET CMP0015 NEW) +cmake_policy(SET CMP0015 OLD) +set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") @@ -7,14 +8,21 @@ aux_source_directory(. SRC_LIST) set(EXECUTABLE ethereum) file(GLOB HEADERS "*.h") -if(ETH_STATIC) + +if (ETH_STATIC) add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS}) else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -include_directories(..) include_directories(${LEVELDB_INCLUDE_DIR}) +include_directories(..) + +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) + +if (MINIUPNPC_LS) +target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) +endif() target_link_libraries(${EXECUTABLE} evm) target_link_libraries(${EXECUTABLE} lll) @@ -23,22 +31,9 @@ target_link_libraries(${EXECUTABLE} p2p) target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} secp256k1) -if(MINIUPNPC_LS) -target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) -endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) target_link_libraries(${EXECUTABLE} gmp) -if("${TARGET_PLATFORM}" STREQUAL "w64") - target_link_libraries(${EXECUTABLE} boost_system-mt-s) - target_link_libraries(${EXECUTABLE} boost_regex-mt-s) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) - target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) - target_link_libraries(${EXECUTABLE} iphlpapi) - target_link_libraries(${EXECUTABLE} ws2_32) - target_link_libraries(${EXECUTABLE} mswsock) - target_link_libraries(${EXECUTABLE} shlwapi) -elseif (APPLE) +if (APPLE) # Latest mavericks boost libraries only come with -mt target_link_libraries(${EXECUTABLE} boost_system-mt) target_link_libraries(${EXECUTABLE} boost_regex-mt) @@ -53,13 +48,6 @@ elseif (UNIX) target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY}) target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -else () - target_link_libraries(${EXECUTABLE} boost_system) - target_link_libraries(${EXECUTABLE} boost_regex) - target_link_libraries(${EXECUTABLE} boost_filesystem) - target_link_libraries(${EXECUTABLE} boost_thread) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) endif () install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) diff --git a/libethereumx/CMakeLists.txt b/libethereumx/CMakeLists.txt index 1c74bf2c3..1063f7981 100644 --- a/libethereumx/CMakeLists.txt +++ b/libethereumx/CMakeLists.txt @@ -1,12 +1,13 @@ cmake_policy(SET CMP0015 NEW) +set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) +include_directories(..) set(EXECUTABLE ethereumx) -# set(CMAKE_INSTALL_PREFIX ../lib) if(ETH_STATIC) add_library(${EXECUTABLE} STATIC ${SRC_LIST}) else() @@ -15,30 +16,22 @@ endif() file(GLOB HEADERS "*.h") -include_directories(..) + +target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) +target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) + +if (MINIUPNPC_LS) +target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) +endif() target_link_libraries(${EXECUTABLE} ethereum) target_link_libraries(${EXECUTABLE} evm) target_link_libraries(${EXECUTABLE} lll) target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} secp256k1) -if(MINIUPNPC_LS) -target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) -endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) -target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) target_link_libraries(${EXECUTABLE} gmp) -if("${TARGET_PLATFORM}" STREQUAL "w64") - target_link_libraries(${EXECUTABLE} boost_system-mt-s) - target_link_libraries(${EXECUTABLE} boost_regex-mt-s) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) - target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) - target_link_libraries(${EXECUTABLE} iphlpapi) - target_link_libraries(${EXECUTABLE} ws2_32) - target_link_libraries(${EXECUTABLE} mswsock) - target_link_libraries(${EXECUTABLE} shlwapi) -elseif (APPLE) +if (APPLE) # Latest mavericks boost libraries only come with -mt target_link_libraries(${EXECUTABLE} boost_system-mt) target_link_libraries(${EXECUTABLE} boost_regex-mt) @@ -53,13 +46,6 @@ elseif (UNIX) target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY}) target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -else () - target_link_libraries(${EXECUTABLE} boost_system) - target_link_libraries(${EXECUTABLE} boost_regex) - target_link_libraries(${EXECUTABLE} boost_filesystem) - target_link_libraries(${EXECUTABLE} boost_thread) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) endif () install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) diff --git a/libevm/CMakeLists.txt b/libevm/CMakeLists.txt index 2812be808..8815d123c 100644 --- a/libevm/CMakeLists.txt +++ b/libevm/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_policy(SET CMP0015 NEW) +set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") @@ -13,8 +14,14 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -include_directories(..) include_directories(${LEVELDB_INCLUDE_DIR}) +include_directories(..) + +if(MINIUPNPC_LS) +target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) +endif() + +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} devcrypto) @@ -22,20 +29,8 @@ target_link_libraries(${EXECUTABLE} evmcore) target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} secp256k1) target_link_libraries(${EXECUTABLE} gmp) -if(MINIUPNPC_LS) -target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) -endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) -if("${TARGET_PLATFORM}" STREQUAL "w64") - target_link_libraries(${EXECUTABLE} boost_system-mt-s) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) - target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) - target_link_libraries(${EXECUTABLE} iphlpapi) - target_link_libraries(${EXECUTABLE} ws2_32) - target_link_libraries(${EXECUTABLE} mswsock) - target_link_libraries(${EXECUTABLE} shlwapi) -elseif (APPLE) +if (APPLE) # Latest mavericks boost libraries only come with -mt target_link_libraries(${EXECUTABLE} boost_system-mt) target_link_libraries(${EXECUTABLE} boost_filesystem-mt) @@ -48,12 +43,6 @@ elseif (UNIX) target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY}) target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -else () - target_link_libraries(${EXECUTABLE} boost_system) - target_link_libraries(${EXECUTABLE} boost_filesystem) - target_link_libraries(${EXECUTABLE} boost_thread) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) endif () install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) diff --git a/libqethereum/CMakeLists.txt b/libqethereum/CMakeLists.txt index c58c30426..bcc49e997 100644 --- a/libqethereum/CMakeLists.txt +++ b/libqethereum/CMakeLists.txt @@ -19,3 +19,5 @@ endif() qt5_use_modules(${EXECUTABLE} Core Gui WebKit WebKitWidgets Widgets Network Quick Qml) target_link_libraries(${EXECUTABLE} ethereum secp256k1 ${JSON_RPC_CPP_LIBRARIES}) +install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) +install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/libserpent/CMakeLists.txt b/libserpent/CMakeLists.txt index c2fe89cc0..06f5dc93b 100644 --- a/libserpent/CMakeLists.txt +++ b/libserpent/CMakeLists.txt @@ -41,5 +41,4 @@ endif () install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) -#install( FILES ${CMAKE_CURRENT_BINARY_DIR}/libserpent.so DESTINATION lib ) From 3015713894354ea32075cb2b672f48796e70a488 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Mon, 1 Dec 2014 21:30:00 +0100 Subject: [PATCH 048/277] common changes --- alethzero/CMakeLists.txt | 6 ++++-- extdep/CMakeLists.txt | 5 +++++ extdep/leveldb.cmake | 4 ++-- libqethereum/CMakeLists.txt | 5 ++++- libweb3jsonrpc/CMakeLists.txt | 3 ++- test/CMakeLists.txt | 1 + 6 files changed, 18 insertions(+), 6 deletions(-) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index b7c41cda3..aa759b37a 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_policy(SET CMP0015 OLD) +#cmake_policy(SET CMP0015 OLD) #set(CMAKE_AUTOMOC OFF) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -37,7 +37,9 @@ endif () qt5_use_modules(${EXECUTABLE} Core) target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES}) -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) +#target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) +#target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_COMMON_LIBRARY}) +#target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_SERVER_LIBRARY}) target_link_libraries(${EXECUTABLE} webthree) target_link_libraries(${EXECUTABLE} qethereum) target_link_libraries(${EXECUTABLE} ethereum) diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index 975207c8b..9ee9e7728 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -22,3 +22,8 @@ include(leveldb.cmake) # will be re-eanbled later # include(miniupnpc.cmake) + + +# BUG +# becouse extdep/cmakelist.txt is subfolder of ethereum project its being install into binary destination on macos. it's a bug + diff --git a/extdep/leveldb.cmake b/extdep/leveldb.cmake index 8b494457f..5399b34b8 100644 --- a/extdep/leveldb.cmake +++ b/extdep/leveldb.cmake @@ -1,11 +1,11 @@ -if(APPLE) +if (APPLE) ExternalProject_Add(leveldb DEPENDS snappy URL https://leveldb.googlecode.com/files/leveldb-1.15.0.tar.gz BINARY_DIR leveldb-prefix/src/leveldb CONFIGURE_COMMAND patch < ${CMAKE_CURRENT_SOURCE_DIR}/leveldb_osx.patch BUILD_COMMAND export ETH_DEPENDENCY_INSTALL_DIR=${ETH_DEPENDENCY_INSTALL_DIR} && make -j 3 - INSTALL_COMMAND cp -rf include/leveldb ${ETH_DEPENDENCY_INSTALL_DIR}/include/ && mv libleveldb.a ${ETH_DEPENDENCY_INSTALL_DIR}/lib && mv libleveldb.dylib.1.15 ${ETH_DEPENDENCY_INSTALL_DIR}/lib/libleveldb.dylib + INSTALL_COMMAND cp -rf include/leveldb ${ETH_DEPENDENCY_INSTALL_DIR}/include/ && cp libleveldb.a ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp libleveldb.dylib.1.15 ${ETH_DEPENDENCY_INSTALL_DIR}/lib/libleveldb.dylib ) elseif(WIN32) ExternalProject_Add(leveldb diff --git a/libqethereum/CMakeLists.txt b/libqethereum/CMakeLists.txt index bcc49e997..56e0ba94a 100644 --- a/libqethereum/CMakeLists.txt +++ b/libqethereum/CMakeLists.txt @@ -17,7 +17,10 @@ else() endif() qt5_use_modules(${EXECUTABLE} Core Gui WebKit WebKitWidgets Widgets Network Quick Qml) -target_link_libraries(${EXECUTABLE} ethereum secp256k1 ${JSON_RPC_CPP_LIBRARIES}) +target_link_libraries(${EXECUTABLE} ethereum) +target_link_libraries(${EXECUTABLE} secp256k1) +target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_COMMON_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_SERVER_LIBRARY}) install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/libweb3jsonrpc/CMakeLists.txt b/libweb3jsonrpc/CMakeLists.txt index 97130718e..fcc9f0ee9 100644 --- a/libweb3jsonrpc/CMakeLists.txt +++ b/libweb3jsonrpc/CMakeLists.txt @@ -19,7 +19,8 @@ endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES}) -target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_LIBRARIES}) +target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_COMMON_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_SERVER_LIBRARY}) if (MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 71b88dbaa..59eb34bc8 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -24,6 +24,7 @@ target_link_libraries(testeth ${CRYPTOPP_LIBRARIES}) if(JSON_RPC_CPP_FOUND) target_link_libraries(testeth ${JSONCPP_LIBRARIES}) target_link_libraries(testeth web3jsonrpc) + target_link_libraries(testeth ${JSON_RPC_CPP_CLIENT_LIBRARY}) endif() target_link_libraries(createRandomTest ethereum) From 0d876d099037edeec634f8ac9e526c5d01683560 Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 2 Dec 2014 10:25:14 +0100 Subject: [PATCH 049/277] common changes --- extdep/jom.cmake | 2 +- extdep/qt.cmake | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/extdep/jom.cmake b/extdep/jom.cmake index 0370eed8e..e5bc5542e 100644 --- a/extdep/jom.cmake +++ b/extdep/jom.cmake @@ -7,7 +7,7 @@ ExternalProject_Add(jom URL http://download.qt-project.org/official_releases/jom/jom.zip BINARY_DIR jom-prefix/src/jom CONFIGURE_COMMAND "" - BUILD_COMMAND echo %cd% + BUILD_COMMAND "" INSTALL_COMMAND cp jom.exe ${ETH_DEPENDENCY_INSTALL_DIR}/bin ) diff --git a/extdep/qt.cmake b/extdep/qt.cmake index 863810d1c..afa40c97b 100644 --- a/extdep/qt.cmake +++ b/extdep/qt.cmake @@ -19,12 +19,6 @@ ExternalProject_Add_Step(qt configure_paths DEPENDERS configure ) -#ExternalProject_Add_Step(qt configure_visual -# COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tools.bat -# DEPENDEES patch -# DEPENDERS configure -# ) - else() endif() From 0f503f1577db9ec48c70402ac82b94d664fac7a1 Mon Sep 17 00:00:00 2001 From: sveneh Date: Tue, 2 Dec 2014 19:01:24 +0100 Subject: [PATCH 050/277] converted whitespaces to tabs according to style guide; handling if json-rpc-cpp is not available --- CMakeLists.txt | 2 +- cmake/EthDependencies.cmake | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 73dc83d80..3b10caa60 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -139,7 +139,7 @@ if (NOT LANGUAGES) add_subdirectory(exp) endif () if(NOT ("${TARGET_PLATFORM}" STREQUAL "w64")) - add_subdirectory(neth) + add_subdirectory(neth) endif () if(QTQML) add_definitions(-DETH_QTQML) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 04e57cce7..776657bd3 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -19,9 +19,10 @@ message(" - Jsoncpp header: ${JSONCPP_INCLUDE_DIRS}") message(" - Jsoncpp lib : ${JSONCPP_LIBRARIES}") # TODO the JsonRpcCpp package does not yet check for correct version number -find_package (JsonRpcCpp 0.3.2 REQUIRED) +# json-rpc-cpp support is currently not mandatory +find_package (JsonRpcCpp 0.3.2) if (${JSON_RPC_CPP_FOUND}) - message (" - json-rpc-cpp header: ${JSON_RPC_CPP_INCLUDE_DIRS}") - message (" - json-rpc-cpp lib : ${JSON_RPC_CPP_LIBRARIES}") + message (" - json-rpc-cpp header: ${JSON_RPC_CPP_INCLUDE_DIRS}") + message (" - json-rpc-cpp lib : ${JSON_RPC_CPP_LIBRARIES}") add_definitions(-DETH_JSONRPC) endif() From 2121aad995d8a2d095b3e6fe2743e7c96fac7600 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 3 Dec 2014 09:34:04 +0100 Subject: [PATCH 051/277] common changes --- alethzero/CMakeLists.txt | 2 +- extdep/CMakeLists.txt | 4 +-- iethxi/CMakeLists.txt | 68 +++++++++++++--------------------------- 3 files changed, 23 insertions(+), 51 deletions(-) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index aa759b37a..5b3704c14 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -94,6 +94,6 @@ elseif ("${TARGET_PLATFORM}" STREQUAL "w64") set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) elseif (UNIX) else () - message(STATUS "platform not supported") + message(ERROR "platform not supported") endif () diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index 9ee9e7728..6c73d3719 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -23,7 +23,5 @@ include(leveldb.cmake) # will be re-eanbled later # include(miniupnpc.cmake) - -# BUG -# becouse extdep/cmakelist.txt is subfolder of ethereum project its being install into binary destination on macos. it's a bug +# if install phase of extep fails, even if libs are already created, the ethereum install will fail diff --git a/iethxi/CMakeLists.txt b/iethxi/CMakeLists.txt index 77c26dd4d..c2203a4f6 100644 --- a/iethxi/CMakeLists.txt +++ b/iethxi/CMakeLists.txt @@ -1,9 +1,4 @@ -cmake_policy(SET CMP0015 NEW) - -if ("${TARGET_PLATFORM}" STREQUAL "w64") - cmake_policy(SET CMP0020 NEW) -endif () - +cmake_policy(SET CMP0015 OLD) set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) @@ -13,31 +8,12 @@ link_directories(../libethcore) link_directories(../libethereum) link_directories(../libqethereum) -# Find Qt5 for Apple and update src_list for windows -if (APPLE) - # homebrew defaults to qt4 and installs qt5 as 'keg-only' - # which places it into /usr/local/opt insteadof /usr/local. - - set(CMAKE_PREFIX_PATH /usr/local/opt/qt5) - include_directories(/usr/local/opt/qt5/include /usr/local/include) -elseif ("${TARGET_PLATFORM}" STREQUAL "w64") - set(SRC_LIST ${SRC_LIST} ../windows/qt_plugin_import.cpp) -elseif (UNIX) - set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ";$ENV{QTDIR}/lib/cmake") -endif () - - -find_package(Qt5Widgets REQUIRED) -find_package(Qt5Gui REQUIRED) -find_package(Qt5Quick REQUIRED) -find_package(Qt5Qml REQUIRED) -find_package(Qt5Network REQUIRED) qt5_wrap_ui(ui_Main.h Main.ui) qt5_add_resources(RESOURCE_ADDED Resources.qrc) # Set name of binary and add_executable() if (APPLE) - set(EXECUTEABLE IEthXi) + set(EXECUTABLE IEthXi) set(CMAKE_INSTALL_PREFIX ./) set(BIN_INSTALL_DIR ".") set(DOC_INSTALL_DIR ".") @@ -49,24 +25,26 @@ if (APPLE) set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}") set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}") set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}") - set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTEABLE}) + set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTABLE}) include(BundleUtilities) - add_executable(${EXECUTEABLE} MACOSX_BUNDLE Main.ui ${RESOURCE_ADDED} ${SRC_LIST}) + add_executable(${EXECUTABLE} MACOSX_BUNDLE Main.ui ${RESOURCE_ADDED} ${SRC_LIST}) else () - set(EXECUTEABLE iethxi) - add_executable(${EXECUTEABLE} Main.ui ${RESOURCE_ADDED} ${SRC_LIST}) + set(EXECUTABLE iethxi) + add_executable(${EXECUTABLE} Main.ui ${RESOURCE_ADDED} ${SRC_LIST}) endif () -qt5_use_modules(${EXECUTEABLE} Core Gui Widgets Network Quick Qml) -target_link_libraries(${EXECUTEABLE} qethereum ethereum secp256k1) +qt5_use_modules(${EXECUTABLE} Core Gui Widgets Network Quick Qml) +target_link_libraries(${EXECUTABLE} qethereum) +target_link_libraries(${EXECUTABLE} ethereum) +target_link_libraries(${EXECUTABLE} secp256k1) if (APPLE) if (${ADDFRAMEWORKS}) - set_target_properties(${EXECUTEABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") + set_target_properties(${EXECUTABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") endif () - SET_SOURCE_FILES_PROPERTIES(${EXECUTEABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) + SET_SOURCE_FILES_PROPERTIES(${EXECUTABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) # This is a workaround for when the build-type defaults to Debug, and when a multi-config generator like xcode is used, where the type # will not be set but defaults to release. @@ -79,7 +57,7 @@ if (APPLE) set(binary_build_dir "${CMAKE_CURRENT_BINARY_DIR}") endif () - set(APPS ${binary_build_dir}/${EXECUTEABLE}.app) + set(APPS ${binary_build_dir}/${EXECUTABLE}.app) # This tool and the next will automatically looked at the linked libraries in order to determine what dependencies are required. Thus, target_link_libaries only needs to add ethereum and secp256k1 (above) install(CODE " @@ -90,7 +68,7 @@ if (APPLE) if (${ADDFRAMEWORKS}) add_custom_target(addframeworks ALL - COMMAND /usr/local/opt/qt5/bin/macdeployqt ${binary_build_dir}/${EXECUTEABLE}.app + COMMAND /usr/local/opt/qt5/bin/macdeployqt ${binary_build_dir}/${EXECUTABLE}.app WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} DEPENDS ${PROJECT_NAME} ) @@ -99,19 +77,15 @@ if (APPLE) elseif ("${TARGET_PLATFORM}" STREQUAL "w64") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-keep-inline-dllexport -static-libgcc -static-libstdc++ -static") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-s -Wl,-subsystem,windows -mthreads -L/usr/x86_64-w64-mingw32/plugins/platforms") - target_link_libraries(${EXECUTEABLE} gcc) - target_link_libraries(${EXECUTEABLE} mingw32 qtmain mswsock iphlpapi qwindows shlwapi Qt5PlatformSupport gdi32 comdlg32 oleaut32 imm32 winmm ole32 uuid ws2_32) - target_link_libraries(${EXECUTEABLE} boost_system-mt-s) - target_link_libraries(${EXECUTEABLE} boost_filesystem-mt-s) - target_link_libraries(${EXECUTEABLE} boost_thread_win32-mt-s) - target_link_libraries(${EXECUTEABLE} Qt5PlatformSupport) + target_link_libraries(${EXECUTABLE} gcc) + target_link_libraries(${EXECUTABLE} mingw32 qtmain mswsock iphlpapi qwindows shlwapi Qt5PlatformSupport gdi32 comdlg32 oleaut32 imm32 winmm ole32 uuid ws2_32) + target_link_libraries(${EXECUTABLE} boost_system-mt-s) + target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) + target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) + target_link_libraries(${EXECUTABLE} Qt5PlatformSupport) set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) elseif (UNIX) else () - target_link_libraries(${EXECUTEABLE} boost_system) - target_link_libraries(${EXECUTEABLE} boost_filesystem) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTEABLE} ${CMAKE_THREAD_LIBS_INIT}) - install( TARGETS ${EXECUTEABLE} RUNTIME DESTINATION bin ) + message(ERROR "platform not supported") endif () From d134a9b4e3b1911a97930a47dfd0b6186ed58d35 Mon Sep 17 00:00:00 2001 From: sveneh Date: Wed, 3 Dec 2014 10:40:55 +0100 Subject: [PATCH 052/277] inital script for CI building. Currently only builds dependencies --- build.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100755 build.py diff --git a/build.py b/build.py new file mode 100755 index 000000000..099a8721d --- /dev/null +++ b/build.py @@ -0,0 +1,27 @@ +#!/usr/bin/python +# cpp-ethereum build script +# to be used from CI server, or to build locally +# uses python instead of bash script for better cross-platform support + +# TODO Initial version. Needs much more improvements + +import argparse +import os +import subprocess + +def build_dependencies(): + if os.path.exists("extdep"): + os.chdir("extdep") + if not os.path.exists("build"): + os.makedirs("build") + os.chdir("build") + subprocess.check_call(["cmake", ".."]) + subprocess.check_call("make") + +parser = argparse.ArgumentParser() +parser.add_argument("cmd", help="what to build") + +args = parser.parse_args() +if args.cmd == "dep": + build_dependencies() + From 7b0688378aa424a3d9badd60633303b719ad3765 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 3 Dec 2014 11:44:12 +0100 Subject: [PATCH 053/277] changed structure of extdep --- extdep/CMakeLists.txt | 30 ++++++++++++------- extdep/{ => cmake}/FindCURL.cmake | 0 extdep/{ => compile}/argtable2.cmake | 0 extdep/{ => compile}/cryptopp.cmake | 0 extdep/{ => compile}/curl.cmake | 0 extdep/{ => compile}/icu.cmake | 0 extdep/{ => compile}/jom.cmake | 0 extdep/{ => compile}/json-rpc-cpp.cmake | 4 +-- extdep/{ => compile}/jsoncpp.cmake | 0 extdep/{ => compile}/leveldb.cmake | 2 +- extdep/{ => compile}/leveldb_osx.patch | 0 extdep/{ => compile}/qt.cmake | 6 ++-- .../qt_configure.bat} | 0 extdep/{ => compile}/qt_osx.patch | 0 extdep/{tools.bat => compile/qt_tools.bat} | 0 extdep/{ => compile}/snappy.cmake | 0 extdep/precompiled/json-rpc-cpp.cmake | 8 +++++ 17 files changed, 34 insertions(+), 16 deletions(-) rename extdep/{ => cmake}/FindCURL.cmake (100%) rename extdep/{ => compile}/argtable2.cmake (100%) rename extdep/{ => compile}/cryptopp.cmake (100%) rename extdep/{ => compile}/curl.cmake (100%) rename extdep/{ => compile}/icu.cmake (100%) rename extdep/{ => compile}/jom.cmake (100%) rename extdep/{ => compile}/json-rpc-cpp.cmake (86%) rename extdep/{ => compile}/jsoncpp.cmake (100%) rename extdep/{ => compile}/leveldb.cmake (91%) rename extdep/{ => compile}/leveldb_osx.patch (100%) rename extdep/{ => compile}/qt.cmake (84%) rename extdep/{configure.bat => compile/qt_configure.bat} (100%) rename extdep/{ => compile}/qt_osx.patch (100%) rename extdep/{tools.bat => compile/qt_tools.bat} (100%) rename extdep/{ => compile}/snappy.cmake (100%) create mode 100644 extdep/precompiled/json-rpc-cpp.cmake diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index 6c73d3719..7b906058a 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -5,20 +5,30 @@ include(ExternalProject) # all dependencies will be installed into this directory, separated by platform string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name) set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install/${_system_name}") +set(ETH_DEPENDENCY_SERVER "http://poc-7.ethdev.com/precompiled/${_system_name}") file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/lib) file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include) file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/bin) -include(icu.cmake) -include(jom.cmake) -include(qt.cmake) -include(curl.cmake) -include(jsoncpp.cmake) -include(argtable2.cmake) -include(json-rpc-cpp.cmake) -include(cryptopp.cmake) -include(snappy.cmake) -include(leveldb.cmake) +if (ETH_COMPILE) + # json-rpc-cpp and its dependencies + include(compile/jsoncpp.cmake) + include(compile/argtable2.cmake) + include(compile/curl.cmake) + include(compile/json-rpc-cpp.cmake) + + # qt at its dependencies + include(compile/icu.cmake) + include(compile/jom.cmake) + include(compile/qt.cmake) + + # leveldb and its dependencies + include(compile/snappy.cmake) + include(compile/leveldb.cmake) + +else() + include(precompiled/json-rpc-cpp.cmake) +endif() # will be re-eanbled later # include(miniupnpc.cmake) diff --git a/extdep/FindCURL.cmake b/extdep/cmake/FindCURL.cmake similarity index 100% rename from extdep/FindCURL.cmake rename to extdep/cmake/FindCURL.cmake diff --git a/extdep/argtable2.cmake b/extdep/compile/argtable2.cmake similarity index 100% rename from extdep/argtable2.cmake rename to extdep/compile/argtable2.cmake diff --git a/extdep/cryptopp.cmake b/extdep/compile/cryptopp.cmake similarity index 100% rename from extdep/cryptopp.cmake rename to extdep/compile/cryptopp.cmake diff --git a/extdep/curl.cmake b/extdep/compile/curl.cmake similarity index 100% rename from extdep/curl.cmake rename to extdep/compile/curl.cmake diff --git a/extdep/icu.cmake b/extdep/compile/icu.cmake similarity index 100% rename from extdep/icu.cmake rename to extdep/compile/icu.cmake diff --git a/extdep/jom.cmake b/extdep/compile/jom.cmake similarity index 100% rename from extdep/jom.cmake rename to extdep/compile/jom.cmake diff --git a/extdep/json-rpc-cpp.cmake b/extdep/compile/json-rpc-cpp.cmake similarity index 86% rename from extdep/json-rpc-cpp.cmake rename to extdep/compile/json-rpc-cpp.cmake index db336f1ac..b4f28a315 100644 --- a/extdep/json-rpc-cpp.cmake +++ b/extdep/compile/json-rpc-cpp.cmake @@ -9,7 +9,7 @@ ExternalProject_Add(json-rpc-cpp GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git GIT_TAG v0.3.2 BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp - CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR} -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev . + CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR}/cmake -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev . BUILD_COMMAND make -j 3 INSTALL_COMMAND make install ) @@ -31,7 +31,7 @@ ExternalProject_Add(json-rpc-cpp GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git GIT_TAG v0.3.2 BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp - CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR} -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST . + CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR}/cmake -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST . BUILD_COMMAND make -j 3 INSTALL_COMMAND make install ) diff --git a/extdep/jsoncpp.cmake b/extdep/compile/jsoncpp.cmake similarity index 100% rename from extdep/jsoncpp.cmake rename to extdep/compile/jsoncpp.cmake diff --git a/extdep/leveldb.cmake b/extdep/compile/leveldb.cmake similarity index 91% rename from extdep/leveldb.cmake rename to extdep/compile/leveldb.cmake index 5399b34b8..a22773d59 100644 --- a/extdep/leveldb.cmake +++ b/extdep/compile/leveldb.cmake @@ -3,7 +3,7 @@ ExternalProject_Add(leveldb DEPENDS snappy URL https://leveldb.googlecode.com/files/leveldb-1.15.0.tar.gz BINARY_DIR leveldb-prefix/src/leveldb - CONFIGURE_COMMAND patch < ${CMAKE_CURRENT_SOURCE_DIR}/leveldb_osx.patch + CONFIGURE_COMMAND patch < ${CMAKE_CURRENT_SOURCE_DIR}/compile/leveldb_osx.patch BUILD_COMMAND export ETH_DEPENDENCY_INSTALL_DIR=${ETH_DEPENDENCY_INSTALL_DIR} && make -j 3 INSTALL_COMMAND cp -rf include/leveldb ${ETH_DEPENDENCY_INSTALL_DIR}/include/ && cp libleveldb.a ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp libleveldb.dylib.1.15 ${ETH_DEPENDENCY_INSTALL_DIR}/lib/libleveldb.dylib ) diff --git a/extdep/leveldb_osx.patch b/extdep/compile/leveldb_osx.patch similarity index 100% rename from extdep/leveldb_osx.patch rename to extdep/compile/leveldb_osx.patch diff --git a/extdep/qt.cmake b/extdep/compile/qt.cmake similarity index 84% rename from extdep/qt.cmake rename to extdep/compile/qt.cmake index 42f4331ab..2ff0e1e5b 100644 --- a/extdep/qt.cmake +++ b/extdep/compile/qt.cmake @@ -2,7 +2,7 @@ if(APPLE) ExternalProject_add(qt URL http://qtmirror.ics.com/pub/qtproject/official_releases/qt/5.3/5.3.2/single/qt-everywhere-opensource-src-5.3.2.tar.gz BINARY_DIR qt-prefix/src/qt - PATCH_COMMAND patch -d qtmultimedia/src/plugins/avfoundation/mediaplayer < ${CMAKE_CURRENT_SOURCE_DIR}/qt_osx.patch + PATCH_COMMAND patch -d qtmultimedia/src/plugins/avfoundation/mediaplayer < ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_osx.patch CONFIGURE_COMMAND ./configure -prefix ${ETH_DEPENDENCY_INSTALL_DIR} -system-zlib -qt-libpng -qt-libjpeg -confirm-license -opensource -nomake tests -release -nomake examples -no-xcb -arch x86_64 BUILD_COMMAND make INSTALL_COMMAND make install @@ -12,8 +12,8 @@ ExternalProject_Add(qt DEPENDS icu jom URL http://download.qt-project.org/official_releases/qt/5.2/5.2.1/single/qt-everywhere-opensource-src-5.2.1.tar.gz BINARY_DIR qt-prefix/src/qt - UPDATE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tools.bat - PATCH_COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/configure.bat qtbase + UPDATE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_tools.bat + PATCH_COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_configure.bat qtbase/configure.bat CONFIGURE_COMMAND configure -prefix ${ETH_DEPENDENCY_INSTALL_DIR} -opensource -confirm-license -release -opengl desktop -platform win32-msvc2013 -icu -I ${ETH_DEPENDENCY_INSTALL_DIR}/include -L ${ETH_DEPENDENCY_INSTALL_DIR}/lib -nomake tests -nomake examples BUILD_COMMAND nmake diff --git a/extdep/configure.bat b/extdep/compile/qt_configure.bat similarity index 100% rename from extdep/configure.bat rename to extdep/compile/qt_configure.bat diff --git a/extdep/qt_osx.patch b/extdep/compile/qt_osx.patch similarity index 100% rename from extdep/qt_osx.patch rename to extdep/compile/qt_osx.patch diff --git a/extdep/tools.bat b/extdep/compile/qt_tools.bat similarity index 100% rename from extdep/tools.bat rename to extdep/compile/qt_tools.bat diff --git a/extdep/snappy.cmake b/extdep/compile/snappy.cmake similarity index 100% rename from extdep/snappy.cmake rename to extdep/compile/snappy.cmake diff --git a/extdep/precompiled/json-rpc-cpp.cmake b/extdep/precompiled/json-rpc-cpp.cmake new file mode 100644 index 000000000..ef60eb54f --- /dev/null +++ b/extdep/precompiled/json-rpc-cpp.cmake @@ -0,0 +1,8 @@ +ExternalProject_Add(json-rpc-cpp + URL ${ETH_DEPENDENCY_SERVER}/json-rpc-cpp.tar.gz + BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND cmake -E copy_directory . ${ETH_DEPENDENCY_INSTALL_DIR} + ) + From 674b73dff757e751d653a256786b1515b017697b Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 3 Dec 2014 16:15:33 +0100 Subject: [PATCH 054/277] handling symlinks --- extdep/CMakeLists.txt | 10 ++++-- extdep/eth_download.cmake | 44 +++++++++++++++++++++++++++ extdep/precompiled/json-rpc-cpp.cmake | 8 ----- 3 files changed, 52 insertions(+), 10 deletions(-) create mode 100644 extdep/eth_download.cmake delete mode 100644 extdep/precompiled/json-rpc-cpp.cmake diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index 7b906058a..54412e6a6 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 2.8) include(ExternalProject) +include(eth_download.cmake) # all dependencies will be installed into this directory, separated by platform string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name) @@ -26,12 +27,17 @@ if (ETH_COMPILE) include(compile/snappy.cmake) include(compile/leveldb.cmake) + # cryptopp + include(compile/cryptopp.cmake) else() - include(precompiled/json-rpc-cpp.cmake) + eth_download("json-rpc-cpp") + eth_download("qt") + eth_download("cryptopp") + #include(compile/snappy.cmake) + eth_download("leveldb") endif() # will be re-eanbled later # include(miniupnpc.cmake) - # if install phase of extep fails, even if libs are already created, the ethereum install will fail diff --git a/extdep/eth_download.cmake b/extdep/eth_download.cmake new file mode 100644 index 000000000..dafd065b7 --- /dev/null +++ b/extdep/eth_download.cmake @@ -0,0 +1,44 @@ +# this macro requires the following variables to be specified: +# +# ETH_DEPENDENCY_SERVER - server from which dependencies should be downloaded +# ETH_DEPENDENCY_INSTALL_DIR - install location for all dependencies +# +# usage: +# +# eth_download("json-rpc-cpp") +# eth_download("json-rpc-cpp" "0.3.2") +# +# TODO: +# check if install_command is handling symlinks correctly on linux and windows + +macro(eth_download eth_package_name) + + set (extra_macro_args ${ARGN}) + if (extra_macro_args GREATER 0) + set(eth_tar_name "${eth_package_name}-${ARGV1}.tar.gz") + else() + set(eth_tar_name "${eth_package_name}.tar.gz") + endif() + + message(STATUS "download path for ${eth_package_name} is : ${ETH_DEPENDENCY_SERVER}/${eth_tar_name}.tar.gz") + + # we need that to copy symlinks + # see http://superuser.com/questions/138587/how-to-copy-symbolic-links + if (APPLE) + set (eth_package_install cp -a . ${ETH_DEPENDENCY_INSTALL_DIR}) + elseif (UNIX) + set (eth_package_install cp -a . ${ETH_DEPENDENCY_INSTALL_DIR}) + else () + set (eth_package_install cmake -E copy_directory . ${ETH_DEPENDENCY_INSTALL_DIR}) + endif() + + + ExternalProject_Add(${eth_package_name} + URL ${ETH_DEPENDENCY_SERVER}/${eth_tar_name} + BINARY_DIR ${eth_package_name}-prefix/src/${eth_package_name} + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND ${eth_package_install} + ) +endmacro() + diff --git a/extdep/precompiled/json-rpc-cpp.cmake b/extdep/precompiled/json-rpc-cpp.cmake deleted file mode 100644 index ef60eb54f..000000000 --- a/extdep/precompiled/json-rpc-cpp.cmake +++ /dev/null @@ -1,8 +0,0 @@ -ExternalProject_Add(json-rpc-cpp - URL ${ETH_DEPENDENCY_SERVER}/json-rpc-cpp.tar.gz - BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND cmake -E copy_directory . ${ETH_DEPENDENCY_INSTALL_DIR} - ) - From f9a56e06182dabe9bab8a344069ea9817dc40cd4 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 3 Dec 2014 21:52:01 +0100 Subject: [PATCH 055/277] improved eth_download.cmake --- cmake/EthDependencies.cmake | 3 +++ extdep/CMakeLists.txt | 14 +++++++++----- extdep/compile/leveldb.cmake | 5 +++-- extdep/eth_download.cmake | 33 +++++++++++++++++++++++++-------- 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 7b938ae5f..bf7ff487a 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -6,6 +6,9 @@ string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name) set (CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install/${_system_name}") +# mac os +# https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/UsingDynamicLibraries.html +set(ENV{DYLD_FALLBACK_LIBRARY_PATH} ${CMAKE_PREFIX_PATH}/lib) # Dependencies must have a version number, to ensure reproducible build. The version provided here is the one that is in the extdep repository. If you use system libraries, version numbers may be different. diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index 54412e6a6..642e10eee 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 2.8) include(ExternalProject) +include(CMakeParseArguments) include(eth_download.cmake) # all dependencies will be installed into this directory, separated by platform @@ -30,11 +31,14 @@ if (ETH_COMPILE) # cryptopp include(compile/cryptopp.cmake) else() - eth_download("json-rpc-cpp") - eth_download("qt") - eth_download("cryptopp") - #include(compile/snappy.cmake) - eth_download("leveldb") + eth_download(json-rpc-cpp VERSION 0.3.2) + eth_download(qt) + eth_download(cryptopp) + eth_download(snappy) + eth_download(leveldb) + + #include(compile/leveldb.cmake) + #eth_download("leveldb") endif() # will be re-eanbled later diff --git a/extdep/compile/leveldb.cmake b/extdep/compile/leveldb.cmake index a22773d59..9774c8c57 100644 --- a/extdep/compile/leveldb.cmake +++ b/extdep/compile/leveldb.cmake @@ -1,9 +1,10 @@ if (APPLE) ExternalProject_Add(leveldb - DEPENDS snappy + #DEPENDS snappy URL https://leveldb.googlecode.com/files/leveldb-1.15.0.tar.gz BINARY_DIR leveldb-prefix/src/leveldb - CONFIGURE_COMMAND patch < ${CMAKE_CURRENT_SOURCE_DIR}/compile/leveldb_osx.patch + #CONFIGURE_COMMAND patch < ${CMAKE_CURRENT_SOURCE_DIR}/compile/leveldb_osx.patch + CONFIGURE_COMMAND "" BUILD_COMMAND export ETH_DEPENDENCY_INSTALL_DIR=${ETH_DEPENDENCY_INSTALL_DIR} && make -j 3 INSTALL_COMMAND cp -rf include/leveldb ${ETH_DEPENDENCY_INSTALL_DIR}/include/ && cp libleveldb.a ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp libleveldb.dylib.1.15 ${ETH_DEPENDENCY_INSTALL_DIR}/lib/libleveldb.dylib ) diff --git a/extdep/eth_download.cmake b/extdep/eth_download.cmake index dafd065b7..1567eafaa 100644 --- a/extdep/eth_download.cmake +++ b/extdep/eth_download.cmake @@ -6,7 +6,13 @@ # usage: # # eth_download("json-rpc-cpp") -# eth_download("json-rpc-cpp" "0.3.2") +# eth_download("json-rpc-cpp" VERSION "0.3.2") +# +# parsing arguments +# http://www.cmake.org/cmake/help/v3.0/module/CMakeParseArguments.html +# +# for macos you may need to specify OSX_SCRIPT with install_name_tool to fix dylib +# http://stackoverflow.com/questions/2985315/using-install-name-tool-whats-going-wrong # # TODO: # check if install_command is handling symlinks correctly on linux and windows @@ -14,30 +20,41 @@ macro(eth_download eth_package_name) set (extra_macro_args ${ARGN}) - if (extra_macro_args GREATER 0) - set(eth_tar_name "${eth_package_name}-${ARGV1}.tar.gz") + set (options) + set (one_value_args VERSION OSX_SCRIPT UNIX_SCRIPT WIN_SCRIPT) + set (multi_value_args) + cmake_parse_arguments (ETH_DOWNLOAD "${options}" "${one_value_args}" "${multi_value_args}" ${extra_macro_args}) + + if (ETH_DOWNLOAD_VERSION) + set(eth_tar_name "${eth_package_name}-${ETH_DOWNLOAD_VERSION}.tar.gz") else() set(eth_tar_name "${eth_package_name}.tar.gz") endif() - message(STATUS "download path for ${eth_package_name} is : ${ETH_DEPENDENCY_SERVER}/${eth_tar_name}.tar.gz") + message(STATUS "download path for ${eth_package_name} is : ${ETH_DEPENDENCY_SERVER}/${eth_tar_name}") # we need that to copy symlinks # see http://superuser.com/questions/138587/how-to-copy-symbolic-links if (APPLE) - set (eth_package_install cp -a . ${ETH_DEPENDENCY_INSTALL_DIR}) + set (eth_package_copy cp -a . ${ETH_DEPENDENCY_INSTALL_DIR}) + set (eth_package_install ${ETH_DOWNLOAD_OSX_SCRIPT}) elseif (UNIX) - set (eth_package_install cp -a . ${ETH_DEPENDENCY_INSTALL_DIR}) + set (eth_package_copy cp -a . ${ETH_DEPENDENCY_INSTALL_DIR}) + set (eth_package_install ${ETH_DOWNLOAD_UNIX_SCRIPT}) else () - set (eth_package_install cmake -E copy_directory . ${ETH_DEPENDENCY_INSTALL_DIR}) + set (eth_package_copy cmake -E copy_directory . ${ETH_DEPENDENCY_INSTALL_DIR}) + set (eth_package_install ${ETH_DOWNLOAD_WIN_SCRIPT}) endif() + if (eth_package_install) + message(STATUS "install script is at: ${eth_package_install}") + endif() ExternalProject_Add(${eth_package_name} URL ${ETH_DEPENDENCY_SERVER}/${eth_tar_name} BINARY_DIR ${eth_package_name}-prefix/src/${eth_package_name} CONFIGURE_COMMAND "" - BUILD_COMMAND "" + BUILD_COMMAND ${eth_package_copy} INSTALL_COMMAND ${eth_package_install} ) endmacro() From 8c03370649c788b1491d6d8e758d39caf3d239e2 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 3 Dec 2014 22:40:32 +0100 Subject: [PATCH 056/277] fixing precompiled dylibs in progress --- extdep/CMakeLists.txt | 3 ++- extdep/eth_download.cmake | 4 +++- extdep/scripts/snappy_osx.sh | 8 ++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100755 extdep/scripts/snappy_osx.sh diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index 642e10eee..8f38cd1bf 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -34,7 +34,8 @@ else() eth_download(json-rpc-cpp VERSION 0.3.2) eth_download(qt) eth_download(cryptopp) - eth_download(snappy) + eth_download(snappy + OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/snappy_osx.sh) eth_download(leveldb) #include(compile/leveldb.cmake) diff --git a/extdep/eth_download.cmake b/extdep/eth_download.cmake index 1567eafaa..0b4d6b6fb 100644 --- a/extdep/eth_download.cmake +++ b/extdep/eth_download.cmake @@ -48,6 +48,8 @@ macro(eth_download eth_package_name) if (eth_package_install) message(STATUS "install script is at: ${eth_package_install}") + else () + set (eth_package_install echo 0) # cause empty string is not handled properly endif() ExternalProject_Add(${eth_package_name} @@ -55,7 +57,7 @@ macro(eth_download eth_package_name) BINARY_DIR ${eth_package_name}-prefix/src/${eth_package_name} CONFIGURE_COMMAND "" BUILD_COMMAND ${eth_package_copy} - INSTALL_COMMAND ${eth_package_install} + INSTALL_COMMAND ${eth_package_install} . ${ETH_DEPENDENCY_INSTALL_DIR} ) endmacro() diff --git a/extdep/scripts/snappy_osx.sh b/extdep/scripts/snappy_osx.sh new file mode 100755 index 000000000..01304fcf1 --- /dev/null +++ b/extdep/scripts/snappy_osx.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +ETH_DEPENDENCY_SOURCE_DIR=$1 +ETH_DEPENDENCY_INSTALL_DIR=$2 + +SNAPPY_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libsnappy.dylib +install_name_tool -id ${SNAPPY_DYLIB} ${SNAPPY_DYLIB} + From aafd5c8d9a22b324483cee79b073be7657378f8a Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 3 Dec 2014 23:10:46 +0100 Subject: [PATCH 057/277] leveldb precompiled dylib is working! --- extdep/CMakeLists.txt | 3 ++- extdep/eth_download.cmake | 15 +++++++++++++-- extdep/scripts/leveldb_osx.sh | 12 ++++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) create mode 100755 extdep/scripts/leveldb_osx.sh diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index 8f38cd1bf..582d8a2f2 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -36,7 +36,8 @@ else() eth_download(cryptopp) eth_download(snappy OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/snappy_osx.sh) - eth_download(leveldb) + eth_download(leveldb + OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/leveldb_osx.sh) #include(compile/leveldb.cmake) #eth_download("leveldb") diff --git a/extdep/eth_download.cmake b/extdep/eth_download.cmake index 0b4d6b6fb..96d6c5122 100644 --- a/extdep/eth_download.cmake +++ b/extdep/eth_download.cmake @@ -8,6 +8,16 @@ # eth_download("json-rpc-cpp") # eth_download("json-rpc-cpp" VERSION "0.3.2") # +# params: +# VERSION - exact version we want to use +# OSX_SCRIPT - script which will be executed on apple in install phase +# UNIX_SCRIPT - script which will be executed on unix in install phase +# WIN_SCRIPT - script which will be executed on win in install phase + +# OSX_SCRIPT, WIN_SCRIPT, UNIX_SCRIPT are taking 2 params: +# $1 is package_source, +# $2 is ETH_DEPENDENCY_INSTALL_DIR +# # parsing arguments # http://www.cmake.org/cmake/help/v3.0/module/CMakeParseArguments.html # @@ -47,7 +57,8 @@ macro(eth_download eth_package_name) endif() if (eth_package_install) - message(STATUS "install script is at: ${eth_package_install}") + message(STATUS "install script: ${eth_package_install}") + set (eth_package_install ${eth_package_install} . ${ETH_DEPENDENCY_INSTALL_DIR}) else () set (eth_package_install echo 0) # cause empty string is not handled properly endif() @@ -57,7 +68,7 @@ macro(eth_download eth_package_name) BINARY_DIR ${eth_package_name}-prefix/src/${eth_package_name} CONFIGURE_COMMAND "" BUILD_COMMAND ${eth_package_copy} - INSTALL_COMMAND ${eth_package_install} . ${ETH_DEPENDENCY_INSTALL_DIR} + INSTALL_COMMAND ${eth_package_install} ) endmacro() diff --git a/extdep/scripts/leveldb_osx.sh b/extdep/scripts/leveldb_osx.sh new file mode 100755 index 000000000..06b4a2dbd --- /dev/null +++ b/extdep/scripts/leveldb_osx.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +ETH_DEPENDENCY_SOURCE_DIR=$1 +ETH_DEPENDENCY_INSTALL_DIR=$2 + +OLD_SNAPPY_DYLIB="/Users/marekkotewicz/ethereum/cpp-ethereum/extdep/install/darwin/lib/libsnappy.1.dylib" +SNAPPY_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libsnappy.dylib +LEVELDB_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libleveldb.dylib + +install_name_tool -id ${LEVELDB_DYLIB} ${LEVELDB_DYLIB} +install_name_tool -change ${OLD_SNAPPY_DYLIB} ${SNAPPY_DYLIB} ${LEVELDB_DYLIB} + From 895a70271d6489a0e1673c2c7f3ab3db435fd6a6 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 4 Dec 2014 00:30:05 +0100 Subject: [PATCH 058/277] fixed json-rpc-cpp install step --- extdep/CMakeLists.txt | 8 +++----- extdep/compile/json-rpc-cpp.cmake | 2 +- extdep/scripts/json-rpc-cpp_osx.sh | 29 +++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 6 deletions(-) create mode 100755 extdep/scripts/json-rpc-cpp_osx.sh diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index 582d8a2f2..274f9755b 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -31,13 +31,11 @@ if (ETH_COMPILE) # cryptopp include(compile/cryptopp.cmake) else() - eth_download(json-rpc-cpp VERSION 0.3.2) + eth_download(json-rpc-cpp OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/json-rpc-cpp_osx.sh) + eth_download(snappy OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/snappy_osx.sh) + eth_download(leveldb OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/leveldb_osx.sh) eth_download(qt) eth_download(cryptopp) - eth_download(snappy - OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/snappy_osx.sh) - eth_download(leveldb - OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/leveldb_osx.sh) #include(compile/leveldb.cmake) #eth_download("leveldb") diff --git a/extdep/compile/json-rpc-cpp.cmake b/extdep/compile/json-rpc-cpp.cmake index b4f28a315..cb2985e58 100644 --- a/extdep/compile/json-rpc-cpp.cmake +++ b/extdep/compile/json-rpc-cpp.cmake @@ -11,7 +11,7 @@ ExternalProject_Add(json-rpc-cpp BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR}/cmake -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev . BUILD_COMMAND make -j 3 - INSTALL_COMMAND make install + INSTALL_COMMAND make install && ${CMAKE_CURRENT_SOURCE_DIR}/scripts/json-rpc-cpp_osx.sh . ${ETH_DEPENDENCY_INSTALL_DIR} ) elseif(WIN32) diff --git a/extdep/scripts/json-rpc-cpp_osx.sh b/extdep/scripts/json-rpc-cpp_osx.sh new file mode 100755 index 000000000..8a6b96c7b --- /dev/null +++ b/extdep/scripts/json-rpc-cpp_osx.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +ETH_DEPENDENCY_SOURCE_DIR=$1 +ETH_DEPENDENCY_INSTALL_DIR=$2 + +OLD_COMMON_DYLIB="libjsonrpccpp-common.0.dylib" + +COMMON_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libjsonrpccpp-common.0.dylib +SERVER_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libjsonrpccpp-server.0.dylib +CLIENT_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libjsonrpccpp-client.0.dylib + +# fix bin +STAB_EXEC=${ETH_DEPENDENCY_INSTALL_DIR}/bin/jsonrpcstub +install_name_tool -change ${OLD_COMMON_DYLIB} ${COMMON_DYLIB} ${STAB_EXEC} + +# fix common +install_name_tool -id ${COMMON_DYLIB} ${COMMON_DYLIB} + +# fix server +install_name_tool -id ${SERVER_DYLIB} ${SERVER_DYLIB} +install_name_tool -change ${OLD_COMMON_DYLIB} ${COMMON_DYLIB} ${SERVER_DYLIB} + +# fix client +install_name_tool -id ${CLIENT_DYLIB} ${CLIENT_DYLIB} +install_name_tool -change ${OLD_COMMON_DYLIB} ${COMMON_DYLIB} ${CLIENT_DYLIB} + +# TODO fix argtable and jsoncpp once they are downloaded as dependencies + + From be820a55fc152b1c42260a1253220349b66e0b22 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 4 Dec 2014 00:47:37 +0100 Subject: [PATCH 059/277] fixed merge bug --- libethereum/Client.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index fcb47474f..d130194cc 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -634,7 +634,6 @@ LogEntries Client::logs(LogFilter const& _f) const } #if ETH_DEBUG else -#if ETH_DEBUG skipped++; #endif if (n == end) From 6b5d89d55907206ad8c8c8d58afbc76649fe38b5 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 4 Dec 2014 09:55:54 +0100 Subject: [PATCH 060/277] removed automocs --- alethzero/CMakeLists.txt | 3 +-- eth/CMakeLists.txt | 2 +- libevmcore/CMakeLists.txt | 1 + liblll/CMakeLists.txt | 1 + libp2p/CMakeLists.txt | 1 + libserpent/CMakeLists.txt | 1 + libsolidity/CMakeLists.txt | 1 + libwebthree/CMakeLists.txt | 1 + libwhisper/CMakeLists.txt | 1 + lllc/CMakeLists.txt | 1 + sc/CMakeLists.txt | 1 - secp256k1/CMakeLists.txt | 1 + solc/CMakeLists.txt | 1 + 13 files changed, 12 insertions(+), 4 deletions(-) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index 5b3704c14..5b6c5c3c4 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -1,5 +1,4 @@ -#cmake_policy(SET CMP0015 OLD) -#set(CMAKE_AUTOMOC OFF) +cmake_policy(SET CMP0015 NEW) set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) diff --git a/eth/CMakeLists.txt b/eth/CMakeLists.txt index 5ccac182b..2b88efbc2 100644 --- a/eth/CMakeLists.txt +++ b/eth/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_policy(SET CMP0015 OLD) +cmake_policy(SET CMP0015 NEW) set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) diff --git a/libevmcore/CMakeLists.txt b/libevmcore/CMakeLists.txt index 738303271..b889e7163 100644 --- a/libevmcore/CMakeLists.txt +++ b/libevmcore/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_policy(SET CMP0015 NEW) +set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") diff --git a/liblll/CMakeLists.txt b/liblll/CMakeLists.txt index 8b1581785..4e6941359 100644 --- a/liblll/CMakeLists.txt +++ b/liblll/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_policy(SET CMP0015 NEW) +set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") diff --git a/libp2p/CMakeLists.txt b/libp2p/CMakeLists.txt index 207d10127..bae400caf 100644 --- a/libp2p/CMakeLists.txt +++ b/libp2p/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_policy(SET CMP0015 NEW) +set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") diff --git a/libserpent/CMakeLists.txt b/libserpent/CMakeLists.txt index 06f5dc93b..315970a7a 100644 --- a/libserpent/CMakeLists.txt +++ b/libserpent/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_policy(SET CMP0015 NEW) +set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index ea2ef4b74..260493b0e 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_policy(SET CMP0015 NEW) +set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") diff --git a/libwebthree/CMakeLists.txt b/libwebthree/CMakeLists.txt index 4ec5b2ea4..dc623a2fa 100644 --- a/libwebthree/CMakeLists.txt +++ b/libwebthree/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_policy(SET CMP0015 NEW) +set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") diff --git a/libwhisper/CMakeLists.txt b/libwhisper/CMakeLists.txt index 62bc5edaf..080c24c05 100644 --- a/libwhisper/CMakeLists.txt +++ b/libwhisper/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_policy(SET CMP0015 NEW) +set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") diff --git a/lllc/CMakeLists.txt b/lllc/CMakeLists.txt index a9b53c74c..3310354fb 100644 --- a/lllc/CMakeLists.txt +++ b/lllc/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_policy(SET CMP0015 NEW) +set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) diff --git a/sc/CMakeLists.txt b/sc/CMakeLists.txt index 9aa23b03b..d977ee967 100644 --- a/sc/CMakeLists.txt +++ b/sc/CMakeLists.txt @@ -31,4 +31,3 @@ endif () install( TARGETS ${EXECUTABLE} DESTINATION bin ) -cmake_policy(SET CMP0015 NEW) diff --git a/secp256k1/CMakeLists.txt b/secp256k1/CMakeLists.txt index 9b017f15f..cdfadb265 100644 --- a/secp256k1/CMakeLists.txt +++ b/secp256k1/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_policy(SET CMP0015 NEW) +set(CMAKE_AUTOMOC OFF) set(CMAKE_ASM_COMPILER "yasm") diff --git a/solc/CMakeLists.txt b/solc/CMakeLists.txt index 386d4a1a8..ab402ed8e 100644 --- a/solc/CMakeLists.txt +++ b/solc/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_policy(SET CMP0015 NEW) +set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) From ecbe9033624cf3705c3f082beb21b1a97ec94bb3 Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 5 Dec 2014 04:55:58 +0100 Subject: [PATCH 061/277] windows build in progress --- cmake/EthDependencies.cmake | 4 ++++ extdep/CMakeLists.txt | 10 +++++++--- extdep/compile/icu.cmake | 3 ++- extdep/compile/jom.cmake | 2 +- extdep/compile/qt.cmake | 5 ++--- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 260d04751..1a8cbfa3b 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -5,6 +5,10 @@ # this must be set to point to the same directory as $ETH_DEPENDENCY_INSTALL_DIR in /extdep directory string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name) set (CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install/${_system_name}") +if (WIN32) + set (CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "C:/Program Files/Windows Kits/8.1/Lib/winv6.3/um/x86") + #set (CMAKE_PREFIX_PATH "C:/Program Files/Windows Kits/8.1/Lib/winv6.3/um/x64") +endif() # Dependencies must have a version number, to ensure reproducible build. The version provided here is the one that is in the extdep repository. If you use system libraries, version numbers may be different. diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index 274f9755b..a2e5fefd5 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -30,15 +30,19 @@ if (ETH_COMPILE) # cryptopp include(compile/cryptopp.cmake) + + # boost + include(compile/boost.cmake) else() eth_download(json-rpc-cpp OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/json-rpc-cpp_osx.sh) - eth_download(snappy OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/snappy_osx.sh) + if (APPLE) + eth_download(snappy OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/snappy_osx.sh) + endif() eth_download(leveldb OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/leveldb_osx.sh) eth_download(qt) eth_download(cryptopp) + eth_download(boost) - #include(compile/leveldb.cmake) - #eth_download("leveldb") endif() # will be re-eanbled later diff --git a/extdep/compile/icu.cmake b/extdep/compile/icu.cmake index 3728280e1..c0c4d46fc 100644 --- a/extdep/compile/icu.cmake +++ b/extdep/compile/icu.cmake @@ -8,7 +8,8 @@ ExternalProject_Add(icu BINARY_DIR icu-prefix/src/icu CONFIGURE_COMMAND "" BUILD_COMMAND "" - INSTALL_COMMAND cmd /c cp lib/* ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R include/uni ${ETH_DEPENDENCY_INSTALL_DIR}/include && cp bin/* ${ETH_DEPENDENCY_INSTALL_DIR}/bin + #INSTALL_COMMAND cmd /c cp lib/* ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R include/uni ${ETH_DEPENDENCY_INSTALL_DIR}/include && cp bin/* ${ETH_DEPENDENCY_INSTALL_DIR}/bin + INSTALL_COMMAND cmake -E copy_directory . ${ETH_DEPENDENCY_INSTALL_DIR} ) else() diff --git a/extdep/compile/jom.cmake b/extdep/compile/jom.cmake index e5bc5542e..17ae6caab 100644 --- a/extdep/compile/jom.cmake +++ b/extdep/compile/jom.cmake @@ -8,7 +8,7 @@ ExternalProject_Add(jom BINARY_DIR jom-prefix/src/jom CONFIGURE_COMMAND "" BUILD_COMMAND "" - INSTALL_COMMAND cp jom.exe ${ETH_DEPENDENCY_INSTALL_DIR}/bin +INSTALL_COMMAND cmake -E copy jom.exe ${ETH_DEPENDENCY_INSTALL_DIR}/bin ) else() diff --git a/extdep/compile/qt.cmake b/extdep/compile/qt.cmake index 2ff0e1e5b..049b3ba94 100644 --- a/extdep/compile/qt.cmake +++ b/extdep/compile/qt.cmake @@ -10,12 +10,11 @@ ExternalProject_add(qt elseif(WIN32) ExternalProject_Add(qt DEPENDS icu jom - URL http://download.qt-project.org/official_releases/qt/5.2/5.2.1/single/qt-everywhere-opensource-src-5.2.1.tar.gz + URL http://qtmirror.ics.com/pub/qtproject/official_releases/qt/5.3/5.3.2/single/qt-everywhere-opensource-src-5.3.2.tar.gz BINARY_DIR qt-prefix/src/qt UPDATE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_tools.bat - PATCH_COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_configure.bat qtbase/configure.bat + #PATCH_COMMAND cmake -E copy ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_configure.bat qtbase/configure.bat CONFIGURE_COMMAND configure -prefix ${ETH_DEPENDENCY_INSTALL_DIR} -opensource -confirm-license -release -opengl desktop -platform win32-msvc2013 -icu -I ${ETH_DEPENDENCY_INSTALL_DIR}/include -L ${ETH_DEPENDENCY_INSTALL_DIR}/lib -nomake tests -nomake examples - BUILD_COMMAND nmake INSTALL_COMMAND nmake install ) From 7bb2de3c4add54ba3e9a7efc695408c37ad9942c Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 5 Dec 2014 05:41:16 +0100 Subject: [PATCH 062/277] cmake project generated on windows --- cmake/EthDependencies.cmake | 10 ++++++++++ cmake/EthDependenciesDeprecated.cmake | 10 +++++----- extdep/CMakeLists.txt | 2 ++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 1a8cbfa3b..ae2483cda 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -44,6 +44,16 @@ find_package (Qt5WebKit REQUIRED) find_package (Qt5WebKitWidgets REQUIRED) +# we have to specify here if we want static and boost version, that is really important + +# win32 msvc 2013 boost +set(Boost_USE_STATIC_LIBS ON) +set(Boost_USE_MULTITHREADED ON) +set(Boost_COMPILER -vc120) + +find_package(Boost 1.55.0 REQUIRED COMPONENTS thread date_time system regex) + + diff --git a/cmake/EthDependenciesDeprecated.cmake b/cmake/EthDependenciesDeprecated.cmake index 47ad733e4..72ad9c769 100644 --- a/cmake/EthDependenciesDeprecated.cmake +++ b/cmake/EthDependenciesDeprecated.cmake @@ -82,11 +82,11 @@ else() message(STATUS "Failed to find the readline headers!") endif () - if (LANGUAGES) - find_package(Boost 1.53 REQUIRED COMPONENTS thread date_time) - else() - find_package(Boost 1.53 REQUIRED COMPONENTS thread date_time system regex) - endif() + #if (LANGUAGES) + # find_package(Boost 1.53 REQUIRED COMPONENTS thread date_time) + #else() + # find_package(Boost 1.53 REQUIRED COMPONENTS thread date_time system regex) + #endif() set(QTQML 1) endif() diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index a2e5fefd5..cea32c80f 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -34,7 +34,9 @@ if (ETH_COMPILE) # boost include(compile/boost.cmake) else() + eth_download(jsoncpp) eth_download(json-rpc-cpp OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/json-rpc-cpp_osx.sh) + if (APPLE) eth_download(snappy OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/snappy_osx.sh) endif() From f990a1ac632d6ff0067e8e14cdd234f49f0a54db Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 5 Dec 2014 10:17:42 +0100 Subject: [PATCH 063/277] mix IDE M1 first commit --- mix/ApplicationCtx.cpp | 62 +++++++- mix/ApplicationCtx.h | 19 ++- mix/AssemblyDebuggerCtrl.cpp | 84 +++++++++++ mix/AssemblyDebuggerCtrl.h | 55 +++++++ mix/AssemblyDebuggerModel.cpp | 111 ++++++++++++++ mix/AssemblyDebuggerModel.h | 49 ++++++ mix/CodeEditorExtensionManager.cpp | 22 ++- mix/CodeEditorExtensionManager.h | 3 +- mix/ConstantCompilationCtrl.cpp | 4 +- mix/ConstantCompilationModel.cpp | 1 + mix/ConstantCompilationModel.h | 2 + mix/DebuggingStateWrapper.cpp | 189 +++++++++++++++++++++++ mix/DebuggingStateWrapper.h | 133 +++++++++++++++++ mix/Extension.cpp | 29 +++- mix/Extension.h | 14 +- mix/KeyEventManager.cpp | 43 ++++++ mix/KeyEventManager.h | 42 ++++++ mix/TransactionBuilder.cpp | 92 ++++++++++++ mix/TransactionBuilder.h | 48 ++++++ mix/main.cpp | 3 + mix/qml.qrc | 3 + mix/qml/BasicMessage.qml | 20 +++ mix/qml/Debugger.qml | 231 +++++++++++++++++++++++++++++ mix/qml/MainContent.qml | 24 ++- mix/qml/js/Debugger.js | 63 ++++++++ mix/qml/main.qml | 40 ++++- 26 files changed, 1353 insertions(+), 33 deletions(-) create mode 100644 mix/AssemblyDebuggerCtrl.cpp create mode 100644 mix/AssemblyDebuggerCtrl.h create mode 100644 mix/AssemblyDebuggerModel.cpp create mode 100644 mix/AssemblyDebuggerModel.h create mode 100644 mix/DebuggingStateWrapper.cpp create mode 100644 mix/DebuggingStateWrapper.h create mode 100644 mix/KeyEventManager.cpp create mode 100644 mix/KeyEventManager.h create mode 100644 mix/TransactionBuilder.cpp create mode 100644 mix/TransactionBuilder.h create mode 100644 mix/qml/BasicMessage.qml create mode 100644 mix/qml/Debugger.qml create mode 100644 mix/qml/js/Debugger.js diff --git a/mix/ApplicationCtx.cpp b/mix/ApplicationCtx.cpp index f97478f3c..52e66dab7 100644 --- a/mix/ApplicationCtx.cpp +++ b/mix/ApplicationCtx.cpp @@ -14,23 +14,83 @@ /** @file ApplicationCtx.cpp * @author Yann yann@ethdev.com * @date 2014 - * Provide an access to the current QQmlApplicationEngine which is used to add QML file on the fly. + * Provides an access to the current QQmlApplicationEngine which is used to add QML file on the fly. * In the future this class can be extended to add more variable related to the context of the application. + * For now ApplicationCtx provides reference to: + * - QQmlApplicationEngine + * - dev::WebThreeDirect (and dev::eth::Client) + * - KeyEventManager */ +#include +#include +#include #include +#include "libdevcrypto/FileSystem.h" +#include "KeyEventManager.h" #include "ApplicationCtx.h" +using namespace dev; using namespace dev::mix; +using namespace dev::eth; ApplicationCtx* ApplicationCtx::Instance = nullptr; +ApplicationCtx::ApplicationCtx(QQmlApplicationEngine* _engine) +{ + m_applicationEngine = _engine; + m_keyEventManager = std::unique_ptr(); + m_webThree = std::unique_ptr(); + m_webThree.reset(new WebThreeDirect(std::string("Mix/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir() + "/Mix", false, {"eth", "shh"})); + m_keyEventManager.reset(new KeyEventManager()); +} + +ApplicationCtx::~ApplicationCtx() +{ + delete m_applicationEngine; +} + QQmlApplicationEngine* ApplicationCtx::appEngine() { return m_applicationEngine; } +dev::eth::Client* ApplicationCtx::getEthereumClient() +{ + return m_webThree.get()->ethereum(); +} + +void ApplicationCtx::initKeyEventManager() +{ + QObject* mainContent = m_applicationEngine->rootObjects().at(0)->findChild("mainContent", Qt::FindChildrenRecursively); + if (mainContent) + { + QObject::connect(mainContent, SIGNAL(keyPressed(QVariant)), m_keyEventManager.get(), SLOT(keyPressed(QVariant))); + } + else + qDebug() << "Unable to find QObject of mainContent.qml. KeyEvent will not be handled!"; +} + +KeyEventManager* ApplicationCtx::getKeyEventManager() +{ + return m_keyEventManager.get(); +} + void ApplicationCtx::setApplicationContext(QQmlApplicationEngine* _engine) { if (Instance == nullptr) Instance = new ApplicationCtx(_engine); } + +void ApplicationCtx::displayMessageDialog(QString _title, QString _message) +{ + QQmlComponent component(m_applicationEngine, QUrl("qrc:/qml/BasicMessage.qml")); + QObject* dialog = component.create(); + dialog->findChild("messageContent", Qt::FindChildrenRecursively)->setProperty("text", _message); + QObject* dialogWin = ApplicationCtx::getInstance()->appEngine()->rootObjects().at(0)->findChild("messageDialog", Qt::FindChildrenRecursively); + QMetaObject::invokeMethod(dialogWin, "close"); + dialogWin->setProperty("contentItem", QVariant::fromValue(dialog)); + dialogWin->setProperty("title", _title); + dialogWin->setProperty("width", "250"); + dialogWin->setProperty("height", "100"); + QMetaObject::invokeMethod(dialogWin, "open"); +} diff --git a/mix/ApplicationCtx.h b/mix/ApplicationCtx.h index 37166ea05..05e4f3bb3 100644 --- a/mix/ApplicationCtx.h +++ b/mix/ApplicationCtx.h @@ -16,14 +16,19 @@ */ /** @file ApplicationCtx.h * @author Yann yann@ethdev.com - * @date 2014 - * Provide an access to the current QQmlApplicationEngine which is used to add QML file on the fly. + * Provides an access to the current QQmlApplicationEngine which is used to add QML file on the fly. * In the future this class can be extended to add more variable related to the context of the application. + * For now ApplicationCtx provides reference to: + * - QQmlApplicationEngine + * - dev::WebThreeDirect (and dev::eth::Client) + * - KeyEventManager */ #pragma once #include +#include "libwebthree/WebThree.h" +#include "KeyEventManager.h" namespace dev { @@ -36,15 +41,21 @@ class ApplicationCtx: public QObject Q_OBJECT public: - ApplicationCtx(QQmlApplicationEngine* _engine) { m_applicationEngine = _engine; } - ~ApplicationCtx() { delete m_applicationEngine; } + ApplicationCtx(QQmlApplicationEngine* _engine); + ~ApplicationCtx(); static ApplicationCtx* getInstance() { return Instance; } static void setApplicationContext(QQmlApplicationEngine* _engine); QQmlApplicationEngine* appEngine(); + dev::eth::Client* getEthereumClient(); + void initKeyEventManager(); + KeyEventManager* getKeyEventManager(); + void displayMessageDialog(QString _title, QString _message); private: static ApplicationCtx* Instance; QQmlApplicationEngine* m_applicationEngine; + std::unique_ptr m_webThree; + std::unique_ptr m_keyEventManager; public slots: void quitApplication() { delete Instance; } diff --git a/mix/AssemblyDebuggerCtrl.cpp b/mix/AssemblyDebuggerCtrl.cpp new file mode 100644 index 000000000..e8b0391d8 --- /dev/null +++ b/mix/AssemblyDebuggerCtrl.cpp @@ -0,0 +1,84 @@ +/* + This file is part of cpp-ethereum. + cpp-ethereum 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. + cpp-ethereum 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 cpp-ethereum. If not, see . +*/ +/** @file AssemblyDebuggerCtrl.h + * @author Yann yann@ethdev.com + * @date 2014 + * display opcode debugging. + */ + +#include +#include +#include +#include "libethereum/Transaction.h" +#include "AssemblyDebuggerModel.h" +#include "AssemblyDebuggerCtrl.h" +#include "TransactionBuilder.h" +#include "KeyEventManager.h" +#include "ApplicationCtx.h" +#include "DebuggingStateWrapper.h" +using namespace dev::mix; + +AssemblyDebuggerCtrl::AssemblyDebuggerCtrl(QTextDocument* _doc): Extension(ExtensionDisplayBehavior::ModalDialog) +{ + m_modelDebugger = std::unique_ptr(new AssemblyDebuggerModel); + m_doc = _doc; +} + +QString AssemblyDebuggerCtrl::contentUrl() const +{ + return QStringLiteral("qrc:/qml/Debugger.qml"); +} + +QString AssemblyDebuggerCtrl::title() const +{ + return "debugger"; +} + +void AssemblyDebuggerCtrl::start() const +{ + //start to listen on F5 + ApplicationCtx::getInstance()->getKeyEventManager()->registerEvent(this, SLOT(keyPressed(int))); +} + +void AssemblyDebuggerCtrl::keyPressed(int _key) +{ + if (_key == Qt::Key_F5) + { + if (!m_modelDebugger->compile(m_doc->toPlainText())) + { + ApplicationCtx::getInstance()->displayMessageDialog("debugger","compilation failed"); + return; + } + + KeyPair ad = KeyPair::create(); + u256 gasPrice = 10000000000000; + u256 gas = 1000000; + u256 amount = 100; + DebuggingContent debuggingContent = m_modelDebugger->getContractInitiationDebugStates(amount, gasPrice, gas, m_doc->toPlainText(), ad); + + //we need to wrap states in a QObject before sending to QML. + QList wStates; + for(int i = 0; i < debuggingContent.states.size(); i++) + { + DebuggingStateWrapper* s = new DebuggingStateWrapper(debuggingContent.executionCode, debuggingContent.executionData.toBytes()); + s->setState(debuggingContent.states.at(i)); + wStates.append(s); + } + std::tuple, QQMLMap*> code = DebuggingStateWrapper::getHumanReadableCode(debuggingContent.executionCode); + ApplicationCtx::getInstance()->appEngine()->rootContext()->setContextProperty("debugStates", QVariant::fromValue(wStates)); + ApplicationCtx::getInstance()->appEngine()->rootContext()->setContextProperty("humanReadableExecutionCode", QVariant::fromValue(std::get<0>(code))); + ApplicationCtx::getInstance()->appEngine()->rootContext()->setContextProperty("bytesCodeMapping", QVariant::fromValue(std::get<1>(code))); + this->addContentOn(this); + }; +} diff --git a/mix/AssemblyDebuggerCtrl.h b/mix/AssemblyDebuggerCtrl.h new file mode 100644 index 000000000..a1642cc14 --- /dev/null +++ b/mix/AssemblyDebuggerCtrl.h @@ -0,0 +1,55 @@ +/* + This file is part of cpp-ethereum. + cpp-ethereum 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. + cpp-ethereum 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 cpp-ethereum. If not, see . +*/ +/** @file AssemblyDebuggerCtrl.h + * @author Yann yann@ethdev.com + * @date 2014 + * Ethereum IDE client. + */ + +#pragma once + +#include +#include "QTextDocument" +#include "Extension.h" +#include "ConstantCompilationModel.h" +#include "AssemblyDebuggerModel.h" + +namespace dev +{ + +namespace mix +{ + +class AssemblyDebuggerCtrl: public Extension +{ + Q_OBJECT + +public: + AssemblyDebuggerCtrl(QTextDocument*); + ~AssemblyDebuggerCtrl() {} + void start() const override; + QString title() const override; + QString contentUrl() const override; + +private: + std::unique_ptr m_modelDebugger; + QTextDocument* m_doc; + +public Q_SLOTS: + void keyPressed(int); +}; + +} + +} diff --git a/mix/AssemblyDebuggerModel.cpp b/mix/AssemblyDebuggerModel.cpp new file mode 100644 index 000000000..c65beac7d --- /dev/null +++ b/mix/AssemblyDebuggerModel.cpp @@ -0,0 +1,111 @@ +/* + This file is part of cpp-ethereum. + cpp-ethereum 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. + cpp-ethereum 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 cpp-ethereum. If not, see . +*/ +/** @file AssemblyDebuggerModel.h + * @author Yann yann@ethdev.com + * @date 2014 + * used as a model to debug contract assembly code. + */ + +#include "libethereum/Executive.h" +#include "libethereum/Transaction.h" +#include "libethereum/ExtVM.h" +#include "libevm/VM.h" +#include "libdevcore/Common.h" +#include "ApplicationCtx.h" +#include "TransactionBuilder.h" +#include "AssemblyDebuggerModel.h" +#include "ConstantCompilationModel.h" +#include "DebuggingStateWrapper.h" +using namespace dev; +using namespace dev::eth; +using namespace dev::mix; + +AssemblyDebuggerModel::AssemblyDebuggerModel() +{ + m_currentExecution = std::unique_ptr(new Executive(m_executiveState)); +} + +DebuggingContent AssemblyDebuggerModel::getContractInitiationDebugStates(dev::bytesConstRef _rawTransaction) +{ + QList states; + Transaction tr(_rawTransaction); + m_currentExecution.get()->create(tr.sender(), tr.value(), tr.gasPrice(), tr.gas(), &tr.data(), tr.sender()); + std::vector levels; + bytes code; + bytesConstRef data; + bool firstIteration = true; + auto onOp = [&](uint64_t steps, Instruction inst, dev::bigint newMemSize, dev::bigint gasCost, void* voidVM, void const* voidExt) + { + VM& vm = *(VM*)voidVM; + ExtVM const& ext = *(ExtVM const*)voidExt; + + if (firstIteration) + { + code = ext.code; + data = ext.data; + firstIteration = false; + } + + if (levels.size() < ext.depth) + levels.push_back(&states.back()); + else + levels.resize(ext.depth); + + states.append(DebuggingState({steps, ext.myAddress, vm.curPC(), inst, newMemSize, vm.gas(), + vm.stack(), vm.memory(), gasCost, ext.state().storage(ext.myAddress), levels})); + }; + + m_currentExecution.get()->go(onOp); + m_currentExecution.get()->finalize(onOp); + + DebuggingContent d; + d.states = states; + d.executionCode = code; + d.executionData = data; + d.contentAvailable = true; + d.message = "ok"; + return d; +} + + +DebuggingContent AssemblyDebuggerModel::getContractInitiationDebugStates(dev::u256 _value, + dev::u256 _gasPrice, + dev::u256 _gas, + QString code, + KeyPair _key) +{ + ConstantCompilationModel compiler; + CompilerResult res = compiler.compile(code); + if (!res.success) + { + DebuggingContent r; + r.contentAvailable = false; + r.message = "compile failed"; + return r; + } + + TransactionBuilder trBuild; + Transaction tr = trBuild.getCreationTransaction(_value, _gasPrice, _gas, res.bytes, + m_executiveState.transactionsFrom(dev::toAddress(_key.secret())), _key.secret()); + bytes b = tr.rlp(); + dev::bytesConstRef bytesRef = &b; + return getContractInitiationDebugStates(bytesRef); +} + +bool AssemblyDebuggerModel::compile(QString code) +{ + ConstantCompilationModel compiler; + CompilerResult res = compiler.compile(code); + return res.success; +} diff --git a/mix/AssemblyDebuggerModel.h b/mix/AssemblyDebuggerModel.h new file mode 100644 index 000000000..3cac98db0 --- /dev/null +++ b/mix/AssemblyDebuggerModel.h @@ -0,0 +1,49 @@ +/* + This file is part of cpp-ethereum. + cpp-ethereum 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. + cpp-ethereum 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 cpp-ethereum. If not, see . +*/ +/** @file AssemblyDebuggerModel.h + * @author Yann yann@ethdev.com + * @date 2014 + * serves as a model to debug contract assembly code. + */ + +#pragma once + +#include +#include +#include "libethereum/State.h" +#include "libethereum/Executive.h" +#include "libdevcore/Common.h" +#include "DebuggingStateWrapper.h" +namespace dev +{ + +namespace mix +{ + +class AssemblyDebuggerModel +{ +public: + AssemblyDebuggerModel(); + DebuggingContent getContractInitiationDebugStates(dev::u256, dev::u256, dev::u256, QString, KeyPair); + DebuggingContent getContractInitiationDebugStates(dev::bytesConstRef); + bool compile(QString code); + +private: + std::unique_ptr m_currentExecution; + dev::eth::State m_executiveState; +}; + +} + +} diff --git a/mix/CodeEditorExtensionManager.cpp b/mix/CodeEditorExtensionManager.cpp index 596aea165..c85292f2b 100644 --- a/mix/CodeEditorExtensionManager.cpp +++ b/mix/CodeEditorExtensionManager.cpp @@ -27,6 +27,7 @@ #include #include #include "ConstantCompilationCtrl.h" +#include "AssemblyDebuggerCtrl.h" #include "features.h" #include "ApplicationCtx.h" #include "CodeEditorExtensionManager.h" @@ -59,22 +60,29 @@ void CodeEditorExtensionManager::loadEditor(QQuickItem* _editor) void CodeEditorExtensionManager::initExtensions() { - //only one for now - std::shared_ptr constantCompilation = std::make_shared(m_doc); - if (constantCompilation.get()->contentUrl() != "") + initExtension(std::make_shared(m_doc)); + initExtension(std::make_shared(m_doc)); +} + +void CodeEditorExtensionManager::initExtension(std::shared_ptr ext) +{ + if (!ext.get()->contentUrl().isEmpty()) { try { - constantCompilation.get()->addContentOn(m_tabView); + if (ext.get()->getDisplayBehavior() == ExtensionDisplayBehavior::Tab) + { + ext.get()->addTabOn(m_tabView); + } } catch (...) { - qDebug() << "Exception when adding content into view."; + qDebug() << "Exception when adding tab into view."; return; } } - constantCompilation.get()->start(); - m_features.append(constantCompilation); + ext.get()->start(); + m_features.append(ext); } void CodeEditorExtensionManager::setEditor(QQuickItem* _editor) diff --git a/mix/CodeEditorExtensionManager.h b/mix/CodeEditorExtensionManager.h index 2b8402bf2..8e8501bc9 100644 --- a/mix/CodeEditorExtensionManager.h +++ b/mix/CodeEditorExtensionManager.h @@ -45,12 +45,13 @@ public: CodeEditorExtensionManager() {} ~CodeEditorExtensionManager(); void initExtensions(); + void initExtension(std::shared_ptr); void setEditor(QQuickItem*); void setTabView(QQuickItem*); private: QQuickItem* m_editor; - QVector> m_features; + QVector> m_features; QQuickItem* m_tabView; QTextDocument* m_doc; void loadEditor(QQuickItem*); diff --git a/mix/ConstantCompilationCtrl.cpp b/mix/ConstantCompilationCtrl.cpp index 06b9c0284..a703e6686 100644 --- a/mix/ConstantCompilationCtrl.cpp +++ b/mix/ConstantCompilationCtrl.cpp @@ -30,7 +30,7 @@ #include "ConstantCompilationModel.h" using namespace dev::mix; -ConstantCompilationCtrl::ConstantCompilationCtrl(QTextDocument* _doc) +ConstantCompilationCtrl::ConstantCompilationCtrl(QTextDocument* _doc): Extension(ExtensionDisplayBehavior::Tab) { m_editor = _doc; m_compilationModel = new ConstantCompilationModel(); @@ -64,7 +64,7 @@ void ConstantCompilationCtrl::compile() resetOutPut(); return; } - CompilerResult res = m_compilationModel->compile(m_editor->toPlainText()); + CompilerResult res = m_compilationModel->compile(m_editor->toPlainText().replace("\t", " ")); writeOutPut(res); } diff --git a/mix/ConstantCompilationModel.cpp b/mix/ConstantCompilationModel.cpp index e06734f59..a6b2f2741 100644 --- a/mix/ConstantCompilationModel.cpp +++ b/mix/ConstantCompilationModel.cpp @@ -42,6 +42,7 @@ CompilerResult ConstantCompilationModel::compile(QString _code) res.success = true; res.comment = "ok"; res.hexCode = QString::fromStdString(dev::eth::disassemble(m_data)); + res.bytes = m_data; } catch (dev::Exception const& _exception) { diff --git a/mix/ConstantCompilationModel.h b/mix/ConstantCompilationModel.h index 4a17853f6..01ad32224 100644 --- a/mix/ConstantCompilationModel.h +++ b/mix/ConstantCompilationModel.h @@ -22,6 +22,7 @@ #pragma once +#include #include namespace dev @@ -34,6 +35,7 @@ struct CompilerResult { QString hexCode; QString comment; + dev::bytes bytes; bool success; }; diff --git a/mix/DebuggingStateWrapper.cpp b/mix/DebuggingStateWrapper.cpp new file mode 100644 index 000000000..877598ca5 --- /dev/null +++ b/mix/DebuggingStateWrapper.cpp @@ -0,0 +1,189 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum 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. + + cpp-ethereum 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 cpp-ethereum. If not, see . +*/ +/** @file DebuggingState.h + * @author Yann yann@ethdev.com + * @date 2014 + * Used to translate c++ type (u256, bytes, ...) into friendly value (to be used by QML). + */ + +#include +#include +#include +#include "libdevcrypto/Common.h" +#include "libevmcore/Instruction.h" +#include "libdevcore/Common.h" +#include "DebuggingStateWrapper.h" +using namespace dev; +using namespace dev::eth; +using namespace dev::mix; + +std::tuple, QQMLMap*> DebuggingStateWrapper::getHumanReadableCode(const bytes& code) +{ + QList codeStr; + QMap codeMapping; + for (unsigned i = 0; i <= code.size(); ++i) + { + byte b = i < code.size() ? code[i] : 0; + try + { + QString s = QString::fromStdString(instructionInfo((Instruction)b).name); + std::ostringstream out; + out << hex << std::setw(4) << std::setfill('0') << i; + codeMapping[i] = codeStr.size(); + int line = i; + if (b >= (byte)Instruction::PUSH1 && b <= (byte)Instruction::PUSH32) + { + unsigned bc = b - (byte)Instruction::PUSH1 + 1; + s = "PUSH 0x" + QString::fromStdString(toHex(bytesConstRef(&code[i + 1], bc))); + i += bc; + } + HumanReadableCode* humanCode = new HumanReadableCode(QString::fromStdString(out.str()) + " " + s, line); + codeStr.append(humanCode); + } + catch (...) + { + qDebug() << QString("Unhandled exception!") << endl << + QString::fromStdString(boost::current_exception_diagnostic_information()); + break; // probably hit data segment + } + } + return std::make_tuple(codeStr, new QQMLMap(codeMapping)); +} + +QString DebuggingStateWrapper::debugStack() +{ + QString stack; + for (auto i: m_state.stack) + stack.prepend(prettyU256(i) + "\n"); + + return stack; +} + +QString DebuggingStateWrapper::debugStorage() +{ + std::stringstream s; + for (auto const& i: m_state.storage) + s << "@" << prettyU256(i.first).toStdString() << "    " << prettyU256(i.second).toStdString(); + + return QString::fromStdString(s.str()); +} + +QString DebuggingStateWrapper::debugMemory() +{ + return QString::fromStdString(memDump(m_state.memory, 16, false)); +} + +QString DebuggingStateWrapper::debugCallData() +{ + + return QString::fromStdString(memDump(m_data, 16, false)); +} + +QStringList DebuggingStateWrapper::levels() +{ + QStringList levelsStr; + for (unsigned i = 0; i <= m_state.levels.size(); ++i) + { + DebuggingState const& s = i ? *m_state.levels[m_state.levels.size() - i] : m_state; + std::ostringstream out; + out << m_state.cur.abridged(); + if (i) + out << " " << instructionInfo(m_state.inst).name << " @0x" << hex << m_state.curPC; + levelsStr.append(QString::fromStdString(out.str())); + } + return levelsStr; +} + +QString DebuggingStateWrapper::headerInfo() +{ + std::ostringstream ss; + ss << dec << " STEP: " << m_state.steps << " | PC: 0x" << hex << m_state.curPC << " : " << dev::eth::instructionInfo(m_state.inst).name << " | ADDMEM: " << dec << m_state.newMemSize << " words | COST: " << dec << m_state.gasCost << " | GAS: " << dec << m_state.gas; + return QString::fromStdString(ss.str()); +} + +QString DebuggingStateWrapper::endOfDebug() +{ + if (m_state.gasCost > m_state.gas) + return "OUT-OF-GAS"; + else if (m_state.inst == Instruction::RETURN && m_state.stack.size() >= 2) + { + unsigned from = (unsigned)m_state.stack.back(); + unsigned size = (unsigned)m_state.stack[m_state.stack.size() - 2]; + unsigned o = 0; + bytes out(size, 0); + for (; o < size && from + o < m_state.memory.size(); ++o) + out[o] = m_state.memory[from + o]; + return "RETURN " + QString::fromStdString(dev::memDump(out, 16, false)); + } + else if (m_state.inst == Instruction::STOP) + return "STOP"; + else if (m_state.inst == Instruction::SUICIDE && m_state.stack.size() >= 1) + return "SUICIDE 0x" + QString::fromStdString(toString(right160(m_state.stack.back()))); + else + return "EXCEPTION"; +} + +QString DebuggingStateWrapper::prettyU256(u256 _n) +{ + unsigned inc = 0; + QString raw; + std::ostringstream s; + if (!(_n >> 64)) + s << " " << (uint64_t)_n << " (0x" << hex << (uint64_t)_n << ")"; + else if (!~(_n >> 64)) + s << " " << (int64_t)_n << " (0x" << hex << (int64_t)_n << ")"; + else if ((_n >> 160) == 0) + { + Address a = right160(_n); + + QString n = QString::fromStdString(a.abridged());//pretty(a); + if (n.isNull()) + s << "0x" << a; + else + s << n.toHtmlEscaped().toStdString() << "(0x" << a.abridged() << ")"; + } + else if ((raw = fromRaw((h256)_n, &inc)).size()) + return "\"" + raw.toHtmlEscaped() + "\"" + (inc ? " + " + QString::number(inc) : ""); + else + s << "" << (h256)_n; + return QString::fromStdString(s.str()); +} + +QString DebuggingStateWrapper::fromRaw(h256 _n, unsigned* _inc) +{ + if (_n) + { + std::string s((char const*)_n.data(), 32); + auto l = s.find_first_of('\0'); + if (!l) + return QString(); + if (l != std::string::npos) + { + auto p = s.find_first_not_of('\0', l); + if (!(p == std::string::npos || (_inc && p == 31))) + return QString(); + if (_inc) + *_inc = (byte)s[31]; + s.resize(l); + } + for (auto i: s) + if (i < 32) + return QString(); + return QString::fromStdString(s); + } + return QString(); +} diff --git a/mix/DebuggingStateWrapper.h b/mix/DebuggingStateWrapper.h new file mode 100644 index 000000000..07716e9ad --- /dev/null +++ b/mix/DebuggingStateWrapper.h @@ -0,0 +1,133 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum 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. + + cpp-ethereum 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 cpp-ethereum. If not, see . +*/ +/** @file DebuggingState.h + * @author Yann yann@ethdev.com + * @date 2014 + * Ethereum IDE client. + */ + +#pragma once + +#include +#include "libethereum/State.h" +#include "libethereum/Executive.h" +#include "libdevcore/Common.h" + +namespace dev +{ + +namespace mix +{ + +struct DebuggingState +{ + uint64_t steps; + dev::Address cur; + dev::u256 curPC; + dev::eth::Instruction inst; + dev::bigint newMemSize; + dev::u256 gas; + dev::u256s stack; + dev::bytes memory; + dev::bigint gasCost; + std::map storage; + std::vector levels; +}; + +struct DebuggingContent +{ + QList states; + bytes executionCode; + bytesConstRef executionData; + bool contentAvailable; + QString message; +}; + +/* contains the line nb of the assembly code and the corresponding index in the code bytes array */ +class HumanReadableCode: public QObject +{ + Q_OBJECT + Q_PROPERTY(QString line READ line) + Q_PROPERTY(int processIndex READ processIndex) + +public: + HumanReadableCode(QString _line, int _processIndex) : m_line(_line), m_processIndex(_processIndex) {} + QString line() { return m_line; } + int processIndex() { return m_processIndex; } + +private: + QString m_line; + int m_processIndex; +}; + +/* used to publish QMap type to QML */ +class QQMLMap : public QObject +{ + Q_OBJECT + +public: + QQMLMap(QMap _map) : m_map(_map) { } + Q_INVOKABLE int getValue(int _key) { return m_map.value(_key); } + +private: + QMap m_map; +}; + +/* used to publish DebuggingState struct to QML */ +class DebuggingStateWrapper : public QObject +{ + Q_OBJECT + Q_PROPERTY(int step READ step) + Q_PROPERTY(int curPC READ curPC) + Q_PROPERTY(int gasCost READ gasCost) + Q_PROPERTY(int gas READ gas) + Q_PROPERTY(QString debugStack READ debugStack) + Q_PROPERTY(QString debugStorage READ debugStorage) + Q_PROPERTY(QString debugMemory READ debugMemory) + Q_PROPERTY(QString debugCallData READ debugCallData) + Q_PROPERTY(QString headerInfo READ headerInfo) + Q_PROPERTY(QString endOfDebug READ endOfDebug) + Q_PROPERTY(QStringList levels READ levels) + +public: + DebuggingStateWrapper(bytes _code, bytes _data) : m_code(_code), m_data(_data) {} + int step() { return (int)m_state.steps; } + int curPC() { return (int)m_state.curPC; } + int gasCost() { return (int)m_state.gasCost; } + int gas() { return (int)m_state.gas; } + QString debugStack(); + QString debugStorage(); + QString debugMemory(); + QString debugCallData(); + QString headerInfo(); + QString endOfDebug(); + QStringList levels(); + DebuggingState state() { return m_state; } + void setState(DebuggingState _state) { m_state = _state; } + static std::tuple, QQMLMap*> getHumanReadableCode(bytes const& code); + +private: + DebuggingState m_state; + bytes m_code; + bytes m_data; + QString prettyU256(u256 _n); + QString fromRaw(h256 _n, unsigned* _inc = nullptr); +}; + +} + +} diff --git a/mix/Extension.cpp b/mix/Extension.cpp index 5aeb0cc17..24cc19aba 100644 --- a/mix/Extension.cpp +++ b/mix/Extension.cpp @@ -25,7 +25,7 @@ using namespace dev; using namespace dev::mix; -void Extension::addContentOn(QObject* _tabView) +void Extension::addTabOn(QObject* _view) { if (contentUrl() == "") return; @@ -33,12 +33,29 @@ void Extension::addContentOn(QObject* _tabView) QVariant returnValue; QQmlComponent* component = new QQmlComponent( ApplicationCtx::getInstance()->appEngine(), - QUrl(this->contentUrl()), _tabView); + QUrl(contentUrl()), _view); - QMetaObject::invokeMethod(_tabView, "addTab", - Q_RETURN_ARG(QVariant, returnValue), - Q_ARG(QVariant, this->title()), - Q_ARG(QVariant, QVariant::fromValue(component))); + QMetaObject::invokeMethod(_view, "addTab", + Q_RETURN_ARG(QVariant, returnValue), + Q_ARG(QVariant, this->title()), + Q_ARG(QVariant, QVariant::fromValue(component))); m_view = qvariant_cast(returnValue); } + +void Extension::addContentOn(QObject* _view) +{ + Q_UNUSED(_view); + if (m_displayBehavior == ExtensionDisplayBehavior::ModalDialog) + { + QQmlComponent component(ApplicationCtx::getInstance()->appEngine(), QUrl(contentUrl())); + QObject* dialog = component.create(); + QObject* dialogWin = ApplicationCtx::getInstance()->appEngine()->rootObjects().at(0)->findChild("dialog", Qt::FindChildrenRecursively); + QMetaObject::invokeMethod(dialogWin, "close"); + dialogWin->setProperty("contentItem", QVariant::fromValue(dialog)); + dialogWin->setProperty("title", title()); + QMetaObject::invokeMethod(dialogWin, "open"); + } + //TODO add more view type. +} + diff --git a/mix/Extension.h b/mix/Extension.h index f8fef0aa6..b697af58b 100644 --- a/mix/Extension.h +++ b/mix/Extension.h @@ -28,19 +28,31 @@ namespace dev namespace mix { +enum ExtensionDisplayBehavior +{ + Tab, + ModalDialog +}; + + class Extension: public QObject { Q_OBJECT public: Extension() {} + Extension(ExtensionDisplayBehavior _displayBehavior) { m_displayBehavior = _displayBehavior; } virtual QString contentUrl() const { return ""; } virtual QString title() const { return ""; } virtual void start() const {} - void addContentOn(QObject* tabView); + void addContentOn(QObject* _tabView); + void addTabOn(QObject* _view); + void setDisplayBehavior(ExtensionDisplayBehavior _displayBehavior) { m_displayBehavior = _displayBehavior; } + ExtensionDisplayBehavior getDisplayBehavior() { return m_displayBehavior; } protected: QObject* m_view; + ExtensionDisplayBehavior m_displayBehavior; }; } diff --git a/mix/KeyEventManager.cpp b/mix/KeyEventManager.cpp new file mode 100644 index 000000000..f5d638869 --- /dev/null +++ b/mix/KeyEventManager.cpp @@ -0,0 +1,43 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum 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. + + cpp-ethereum 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 cpp-ethereum. If not, see . +*/ +/** @file KeyEventManager.cpp + * @author Yann yann@ethdev.com + * @date 2014 + * Used as an event handler for all classes which need keyboard interactions. + * Can be improve by adding the possibility to register to a specific key. + */ + +#include +#include +#include "KeyEventManager.h" + +void KeyEventManager::registerEvent(const QObject* _receiver, const char* _slot) +{ + QObject::connect(this, SIGNAL(onKeyPressed(int)), _receiver, _slot); +} + +void KeyEventManager::unRegisterEvent(QObject* _receiver) +{ + QObject::disconnect(_receiver); +} + +void KeyEventManager::keyPressed(QVariant _event) +{ + emit onKeyPressed(_event.toInt()); +} + + diff --git a/mix/KeyEventManager.h b/mix/KeyEventManager.h new file mode 100644 index 000000000..ecd768c4c --- /dev/null +++ b/mix/KeyEventManager.h @@ -0,0 +1,42 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum 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. + + cpp-ethereum 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 cpp-ethereum. If not, see . +*/ +/** @file KeyEventManager.h + * @author Yann yann@ethdev.com + * @date 2014 + * use as an event handler for all classes which need keyboard interactions + */ + +#pragma once + +#include + +class KeyEventManager: public QObject +{ + Q_OBJECT + +public: + KeyEventManager() {} + void registerEvent(const QObject* receiver, const char* slot); + void unRegisterEvent(QObject* receiver); + +signals: + void onKeyPressed(int); + +public Q_SLOTS: + void keyPressed(QVariant event); +}; + diff --git a/mix/TransactionBuilder.cpp b/mix/TransactionBuilder.cpp new file mode 100644 index 000000000..ce274fa00 --- /dev/null +++ b/mix/TransactionBuilder.cpp @@ -0,0 +1,92 @@ +/* + This file is part of cpp-ethereum. + cpp-ethereum 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. + cpp-ethereum 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 cpp-ethereum. If not, see . +*/ +/** @file TransactionBuilder.cpp + * @author Yann yann@ethdev.com + * @date 2014 + * Ethereum IDE client. + */ + +#include "libethereum/Executive.h" +#include "libdevcore/Common.h" +#include "ApplicationCtx.h" +#include "TransactionBuilder.h" +using namespace dev::mix; +using namespace dev::eth; +using namespace dev; + +Transaction TransactionBuilder::getCreationTransaction(u256 _value, u256 _gasPrice, u256 _gas, + bytes _data, u256 _nonce, Secret _secret) const +{ + return Transaction(_value, _gasPrice, _gas, _data, _nonce, _secret); +} + +Transaction TransactionBuilder::getBasicTransaction(u256 _value, u256 _gasPrice, u256 _gas, + QString address, bytes _data, u256 _nonce, Secret _secret) const +{ + return Transaction(_value, _gasPrice, _gas, fromString(address), _data, _nonce, _secret); +} + +int TransactionBuilder::fromHex(char _i) const +{ + if (_i >= '0' && _i <= '9') + return _i - '0'; + if (_i >= 'a' && _i <= 'f') + return _i - 'a' + 10; + if (_i >= 'A' && _i <= 'F') + return _i - 'A' + 10; + BOOST_THROW_EXCEPTION(BadHexCharacter() << errinfo_invalidSymbol(_i)); +} + +bytes TransactionBuilder::fromHex(std::string const& _s) const +{ + unsigned s = (_s[0] == '0' && _s[1] == 'x') ? 2 : 0; + std::vector ret; + ret.reserve((_s.size() - s + 1) / 2); + + if (_s.size() % 2) + try + { + ret.push_back(fromHex(_s[s++])); + } + catch (...){ ret.push_back(0); cwarn << boost::current_exception_diagnostic_information(); } + for (unsigned i = s; i < _s.size(); i += 2) + try + { + ret.push_back((byte)(fromHex(_s[i]) * 16 + fromHex(_s[i + 1]))); + } + catch (...){ ret.push_back(0); cwarn << boost::current_exception_diagnostic_information(); } + return ret; +} + +Address TransactionBuilder::fromString(QString const& _a) const +{ + Client* ethClient = ApplicationCtx::getInstance()->getEthereumClient(); + std::string sn = _a.toStdString(); + if (sn.size() > 32) + sn.resize(32); + h256 n; + memcpy(n.data(), sn.data(), sn.size()); + memset(n.data() + sn.size(), 0, 32 - sn.size()); + if (_a.size() == 40) + return Address(fromHex(_a.toStdString())); + else + { + //we try to resolve the recipient adress using nameReg contract state + const Address c_config = Address("661005d2720d855f1d9976f88bb10c1a3398c77f"); //NameReg contract + if (h160 nameReg = (u160)ethClient->stateAt(c_config, 0)) + if (h256 a = ethClient->stateAt(nameReg, n)) + return right160(a); + } + return Address(); // should maybe throws exception instead of returning blank address. +} diff --git a/mix/TransactionBuilder.h b/mix/TransactionBuilder.h new file mode 100644 index 000000000..261d3060f --- /dev/null +++ b/mix/TransactionBuilder.h @@ -0,0 +1,48 @@ +/* + This file is part of cpp-ethereum. + cpp-ethereum 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. + cpp-ethereum 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 cpp-ethereum. If not, see . +*/ +/** @file TransactionBuilder.h + * @author Yann yann@ethdev.com + * @date 2014 + * Ethereum IDE client. + */ + +#pragma once + +#include +#include "libdevcore/Common.h" +#include "libethereum/Transaction.h" + +namespace dev +{ + +namespace mix +{ + +class TransactionBuilder +{ +public: + TransactionBuilder() {} + dev::eth::Transaction getBasicTransaction(dev::u256 _value, dev::u256 _gasPrice, dev::u256 _gas, + QString address, bytes _data, dev::u256 _nonce, Secret _secret) const; + dev::eth::Transaction getCreationTransaction(dev::u256 _value, dev::u256 _gasPrice, dev::u256 _gas, + dev::bytes _data, dev::u256 _nonce, Secret _secret) const; +private: + bytes fromHex(std::string const& _s) const; + int fromHex(char _i) const; + Address fromString(QString const& _a) const; +}; + +} + +} diff --git a/mix/main.cpp b/mix/main.cpp index 537941290..4f707f47a 100644 --- a/mix/main.cpp +++ b/mix/main.cpp @@ -35,6 +35,9 @@ int main(int _argc, char *_argv[]) QQmlApplicationEngine* engine = new QQmlApplicationEngine(); ApplicationCtx::setApplicationContext(engine); QObject::connect(&app, SIGNAL(lastWindowClosed()), ApplicationCtx::getInstance(), SLOT(quitApplication())); //use to kill ApplicationContext and other stuff + engine->load(QUrl(QStringLiteral("qrc:/qml/main.qml"))); + + ApplicationCtx::getInstance()->initKeyEventManager(); //has to be called after the loading of the main view. return app.exec(); } diff --git a/mix/qml.qrc b/mix/qml.qrc index 267427ce5..2fa92d661 100644 --- a/mix/qml.qrc +++ b/mix/qml.qrc @@ -4,5 +4,8 @@ qml/main.qml qml/MainContent.qml qml/TabStyle.qml + qml/Debugger.qml + qml/js/Debugger.js + qml/BasicMessage.qml diff --git a/mix/qml/BasicMessage.qml b/mix/qml/BasicMessage.qml new file mode 100644 index 000000000..14ddbcf0d --- /dev/null +++ b/mix/qml/BasicMessage.qml @@ -0,0 +1,20 @@ +import QtQuick 2.3 +import QtQuick.Controls.Styles 1.2 +import QtQuick.Controls 1.2 +import QtQuick.Dialogs 1.2 +import QtQuick.Layouts 1.1 + +Rectangle { + anchors.fill: parent + color: "lightgrey" + Label + { + width: parent.width + height: parent.height + horizontalAlignment: "AlignHCenter" + verticalAlignment: "AlignVCenter" + objectName: "messageContent" + id: messageTxt + text: "" + } +} diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml new file mode 100644 index 000000000..1c79e43ce --- /dev/null +++ b/mix/qml/Debugger.qml @@ -0,0 +1,231 @@ +import QtQuick 2.3 +import QtQuick.Controls.Styles 1.2 +import QtQuick.Controls 1.2 +import QtQuick.Dialogs 1.2 +import QtQuick.Layouts 1.1 +import "js/Debugger.js" as Debugger + +Rectangle { + anchors.fill: parent; + Rectangle { + id: headerInfo + width: parent.width + height: 30 + anchors.top: parent.top + Label { + anchors.centerIn: parent + font.family: "Verdana" + font.pointSize: 9 + font.italic: true + id: headerInfoLabel + } + + } + + Keys.onPressed: { + if (event.key === Qt.Key_F10) + Debugger.moveSelection(1); + else if (event.key === Qt.Key_F9) + Debugger.moveSelection(-1); + } + + Rectangle { + id: stateListContainer + focus: true + anchors.top: headerInfo.bottom + anchors.left: parent.left + height: parent.height - 30 + width: parent.width * 0.5 + + ListView { + anchors.top: parent.top + height: parent.height * 0.55 + width: 200 + anchors.horizontalCenter: parent.horizontalCenter + id: statesList + Component.onCompleted: Debugger.init(); + model: humanReadableExecutionCode + delegate: renderDelegate + highlight: highlightBar + highlightFollowsCurrentItem: true + } + + Component { + id: highlightBar + Rectangle { + height: statesList.currentItem.height + width: statesList.currentItem.width + border.color: "orange" + border.width: 1 + Behavior on y { SpringAnimation { spring: 2; damping: 0.1 } } + } + } + + Component { + id: renderDelegate + Item { + id: wrapperItem + height:20 + width: parent.width + Text { + anchors.centerIn: parent + text: line + font.pointSize: 9 + } + } + } + + Rectangle { + anchors.top: statesList.bottom + height: parent.height * 0.30 + width: parent.width + + Label { + id: callStackLabel + anchors.top: statesList.bottom + anchors.bottomMargin: 10 + horizontalAlignment: "AlignHCenter" + font.family: "Verdana" + font.pointSize: 8 + font.letterSpacing: 2 + width: parent.width + height: 15 + text: "callstack" + } + + ListView { + height: parent.height - 15 + width: 200 + anchors.top: callStackLabel.bottom + anchors.horizontalCenter: parent.horizontalCenter + id: levelList + delegate: Component { + Item { + Text { + font.family: "Verdana" + font.pointSize: 8 + text: modelData + } + } + } + } + } + } + + Rectangle { + anchors.topMargin: 5 + anchors.bottomMargin: 10 + anchors.rightMargin: 10 + height: parent.height - 30 + width: parent.width * 0.5 + anchors.right: parent.right + anchors.top: headerInfo.bottom + anchors.bottom: parent.bottom + + Rectangle { + id: debugStack + anchors.top: parent.top + width: parent.width + height: parent.height * 0.25 + + Label { + horizontalAlignment: "AlignHCenter" + font.family: "Verdana" + font.pointSize: 8 + font.letterSpacing: 2 + width: parent.width + height: 15 + anchors.top : parent.top + text: "debug stack" + } + TextArea { + anchors.bottom: parent.bottom + width: parent.width + font.family: "Verdana" + font.pointSize: 8 + font.letterSpacing: 2 + height: parent.height - 15 + id:debugStackTxt + readOnly: true; + } + } + + Rectangle { + id: debugMemory + anchors.top: debugStack.bottom + width: parent.width + height: parent.height * 0.25 + Label { + horizontalAlignment: "AlignHCenter" + font.family: "Verdana" + font.pointSize: 8 + font.letterSpacing: 2 + width: parent.width + height: 15 + anchors.top : parent.top + text: "debug memory" + } + TextArea { + anchors.bottom: parent.bottom + width: parent.width + font.family: "Verdana" + font.pointSize: 8 + font.letterSpacing: 2 + height: parent.height - 15 + id: debugMemoryTxt + readOnly: true; + } + } + + Rectangle { + id: debugStorage + anchors.top: debugMemory.bottom + width: parent.width + height: parent.height * 0.25 + Label { + horizontalAlignment: "AlignHCenter" + font.family: "Verdana" + font.pointSize: 8 + font.letterSpacing: 2 + width: parent.width + height: 15 + anchors.top : parent.top + text: "debug storage" + } + TextArea { + anchors.bottom: parent.bottom + width: parent.width + font.family: "Verdana" + font.pointSize: 8 + font.letterSpacing: 2 + height: parent.height - 15 + id:debugStorageTxt + readOnly: true; + } + } + + Rectangle { + id: debugCallData + anchors.top: debugStorage.bottom + width: parent.width + height: parent.height * 0.25 + Label { + horizontalAlignment: "AlignHCenter" + font.family: "Verdana" + font.pointSize: 8 + font.letterSpacing: 2 + width: parent.width + height: 15 + anchors.top : parent.top + text: "debug calldata" + } + TextArea { + anchors.bottom: parent.bottom + width: parent.width + height: parent.height - 15 + id: debugCallDataTxt + readOnly: true; + } + } + } +} diff --git a/mix/qml/MainContent.qml b/mix/qml/MainContent.qml index bd4737c3b..821b48913 100644 --- a/mix/qml/MainContent.qml +++ b/mix/qml/MainContent.qml @@ -1,10 +1,18 @@ -import QtQuick 2.2 -import QtQuick.Controls 1.1 +import QtQuick 2.3 +import QtQuick.Controls 1.2 import QtQuick.Layouts 1.0 -import QtQuick.Controls.Styles 1.1 +import QtQuick.Controls.Styles 1.2 import CodeEditorExtensionManager 1.0 Rectangle { + objectName: "mainContent" + signal keyPressed(variant event) + focus: true + Keys.enabled: true + Keys.onPressed: + { + root.keyPressed(event.key); + } anchors.fill: parent height: parent.height width: parent.width; @@ -26,11 +34,11 @@ Rectangle { anchors.centerIn: parent tabChangesFocus: false Keys.onPressed: { - if (event.key === Qt.Key_Tab) { - codeEditor.insert(codeEditor.cursorPosition, "\t"); - event.accepted = true; + if (event.key === Qt.Key_Tab) { + codeEditor.insert(codeEditor.cursorPosition, "\t"); + event.accepted = true; + } } - } } } Rectangle { @@ -46,7 +54,7 @@ Rectangle { style: TabStyle {} } } - CodeEditorExtensionManager{ + CodeEditorExtensionManager { tabView: contextualTabs editor: codeEditor } diff --git a/mix/qml/js/Debugger.js b/mix/qml/js/Debugger.js new file mode 100644 index 000000000..ddaa362a6 --- /dev/null +++ b/mix/qml/js/Debugger.js @@ -0,0 +1,63 @@ +//humanReadableExecutionCode => contain human readable code. +//debugStates => contain all debug states. +//bytesCodeMapping => mapping between humanReadableExecutionCode and bytesCode. +//statesList => ListView + +var currentSelectedState = null; +function init() +{ + currentSelectedState = 0; + select(currentSelectedState); +} + +function moveSelection(incr) +{ + if (currentSelectedState + incr >= 0) + { + if (currentSelectedState + incr < debugStates.length) + { + select(currentSelectedState + incr); + } + else + { + endOfDebug(); + } + } +} + +function select(stateIndex) +{ + var state = debugStates[stateIndex]; + var codeStr = bytesCodeMapping.getValue(state.curPC); + highlightSelection(codeStr); + currentSelectedState = codeStr; + completeCtxInformation(state); + levelList.model = state.levels; + levelList.update(); +} + +function highlightSelection(index) +{ + console.log(index); + statesList.currentIndex = index; +} + +function completeCtxInformation(state) +{ + debugStackTxt.text = state.debugStack; + debugStorageTxt.text = state.debugStorage; + debugMemoryTxt.text = state.debugMemory; + debugCallDataTxt.text = state.debugCallData; + headerInfoLabel.text = state.headerInfo +} + +function endOfDebug() +{ + var state = debugStates[debugStates.length - 1]; + debugStorageTxt.text = ""; + debugCallDataTxt.text = ""; + debugStackTxt.text = ""; + debugMemoryTxt.text = state.endOfDebug + var gascost = state.gas - state.gasCost; + headerInfoLabel.text = "EXIT | GAS: " + gascost; +} diff --git a/mix/qml/main.qml b/mix/qml/main.qml index 3553f7710..05b29eb62 100644 --- a/mix/qml/main.qml +++ b/mix/qml/main.qml @@ -1,15 +1,22 @@ import QtQuick 2.2 import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.1 +import QtQuick.Dialogs 1.2 +import QtQuick.Layouts 1.1 +import QtQuick.Window 2.0 import CodeEditorExtensionManager 1.0 ApplicationWindow { + id: mainApplication visible: true - width: 1000 - height: 480 + x: Screen.width / 2 - width / 2 + y: Screen.height / 2 - height / 2 + width: 1200 + height: 600 minimumWidth: 400 minimumHeight: 300 title: qsTr("mix") + menuBar: MenuBar { Menu { title: qsTr("File") @@ -19,6 +26,33 @@ ApplicationWindow { } } } - MainContent{ + + MainContent { + } + + Dialog { + x: mainApplication.x + (mainApplication.width - width) / 2 + y: mainApplication.y + (mainApplication.height - height) / 2 + objectName: "dialog" + id: dialog + height: 400 + width: 700 + modality: Qt.WindowModal + contentItem: Rectangle { + objectName: "dialogContent" + } + } + + Dialog { + x: mainApplication.x + (mainApplication.width - width) / 2 + y: mainApplication.y + (mainApplication.height - height) / 2 + objectName: "messageDialog" + id: messageDialog + height: 150 + width: 200 + modality: Qt.WindowModal + contentItem: Rectangle { + objectName: "messageContent" + } } } From 803b47161ec05acea00129d4afa6dd93c6c943f0 Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 5 Dec 2014 11:27:09 +0100 Subject: [PATCH 064/277] debug modal dialog UI correction --- mix/qml/Debugger.qml | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml index 1c79e43ce..490f49f61 100644 --- a/mix/qml/Debugger.qml +++ b/mix/qml/Debugger.qml @@ -7,7 +7,9 @@ import "js/Debugger.js" as Debugger Rectangle { anchors.fill: parent; + color: "lightgrey" Rectangle { + color: "transparent" id: headerInfo width: parent.width height: 30 @@ -30,8 +32,10 @@ Rectangle { } Rectangle { + color: "transparent" id: stateListContainer focus: true + anchors.topMargin: 10 anchors.top: headerInfo.bottom anchors.left: parent.left height: parent.height - 30 @@ -39,7 +43,7 @@ Rectangle { ListView { anchors.top: parent.top - height: parent.height * 0.55 + height: parent.height * 0.60 width: 200 anchors.horizontalCenter: parent.horizontalCenter id: statesList @@ -65,7 +69,7 @@ Rectangle { id: renderDelegate Item { id: wrapperItem - height:20 + height: 20 width: parent.width Text { anchors.centerIn: parent @@ -76,13 +80,14 @@ Rectangle { } Rectangle { + id: callStackPanel anchors.top: statesList.bottom - height: parent.height * 0.30 + height: parent.height * 0.35 width: parent.width - + anchors.topMargin: 13 + color: "transparent" Label { id: callStackLabel - anchors.top: statesList.bottom anchors.bottomMargin: 10 horizontalAlignment: "AlignHCenter" font.family: "Verdana" @@ -113,6 +118,7 @@ Rectangle { } Rectangle { + color: "transparent" anchors.topMargin: 5 anchors.bottomMargin: 10 anchors.rightMargin: 10 @@ -127,7 +133,7 @@ Rectangle { anchors.top: parent.top width: parent.width height: parent.height * 0.25 - + color: "transparent" Label { horizontalAlignment: "AlignHCenter" font.family: "Verdana" @@ -155,6 +161,7 @@ Rectangle { anchors.top: debugStack.bottom width: parent.width height: parent.height * 0.25 + color: "transparent" Label { horizontalAlignment: "AlignHCenter" font.family: "Verdana" @@ -182,6 +189,7 @@ Rectangle { anchors.top: debugMemory.bottom width: parent.width height: parent.height * 0.25 + color: "transparent" Label { horizontalAlignment: "AlignHCenter" font.family: "Verdana" @@ -209,6 +217,7 @@ Rectangle { anchors.top: debugStorage.bottom width: parent.width height: parent.height * 0.25 + color: "transparent" Label { horizontalAlignment: "AlignHCenter" font.family: "Verdana" From b5323f75e6b6945e0ac36aae4fb2da84bf1fa64c Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 5 Dec 2014 12:48:34 +0100 Subject: [PATCH 065/277] common changes in windows build --- cmake/EthCompilerSettings.cmake | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index 8530a54b7..2757eb9ad 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -3,15 +3,16 @@ # C++11 check and activation if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") + set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB") execute_process( COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) if (NOT (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7)) message(FATAL_ERROR "${PROJECT_NAME} requires g++ 4.7 or greater.") endif () elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") + set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") + set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -DSHAREDLIB") else () message(FATAL_ERROR "Your C++ compiler does not support C++11. You have ${CMAKE_CXX_COMPILER_ID}") endif () @@ -19,7 +20,7 @@ endif () # Initialize CXXFLAGS -set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB") +# CMAKE_CXX_FLAGS was set before set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DETH_DEBUG") set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE") set(CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG -DETH_RELEASE") From dbc5201e98c1fdc1e09f1fe3108a6c10f6b20fc1 Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 5 Dec 2014 12:57:09 +0100 Subject: [PATCH 066/277] - coding standards. - set 'parent' on QObject custom class to ensure object deletion. --- mix/ApplicationCtx.cpp | 6 ++---- mix/AssemblyDebuggerCtrl.cpp | 2 +- mix/AssemblyDebuggerModel.cpp | 1 - mix/AssemblyDebuggerModel.h | 1 + mix/CodeEditorExtensionManager.cpp | 12 ++++++------ mix/ConstantCompilationModel.h | 2 +- mix/DebuggingStateWrapper.cpp | 6 +++--- mix/DebuggingStateWrapper.h | 6 +++--- mix/qml/Debugger.qml | 2 +- 9 files changed, 18 insertions(+), 20 deletions(-) diff --git a/mix/ApplicationCtx.cpp b/mix/ApplicationCtx.cpp index 52e66dab7..99d9bee4c 100644 --- a/mix/ApplicationCtx.cpp +++ b/mix/ApplicationCtx.cpp @@ -38,10 +38,8 @@ ApplicationCtx* ApplicationCtx::Instance = nullptr; ApplicationCtx::ApplicationCtx(QQmlApplicationEngine* _engine) { m_applicationEngine = _engine; - m_keyEventManager = std::unique_ptr(); - m_webThree = std::unique_ptr(); - m_webThree.reset(new WebThreeDirect(std::string("Mix/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir() + "/Mix", false, {"eth", "shh"})); - m_keyEventManager.reset(new KeyEventManager()); + m_keyEventManager = std::unique_ptr(new KeyEventManager()); + m_webThree = std::unique_ptr(new WebThreeDirect(std::string("Mix/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir() + "/Mix", false, {"eth", "shh"})); } ApplicationCtx::~ApplicationCtx() diff --git a/mix/AssemblyDebuggerCtrl.cpp b/mix/AssemblyDebuggerCtrl.cpp index e8b0391d8..94d8bf6cb 100644 --- a/mix/AssemblyDebuggerCtrl.cpp +++ b/mix/AssemblyDebuggerCtrl.cpp @@ -75,7 +75,7 @@ void AssemblyDebuggerCtrl::keyPressed(int _key) s->setState(debuggingContent.states.at(i)); wStates.append(s); } - std::tuple, QQMLMap*> code = DebuggingStateWrapper::getHumanReadableCode(debuggingContent.executionCode); + std::tuple, QQMLMap*> code = DebuggingStateWrapper::getHumanReadableCode(debuggingContent.executionCode, this); ApplicationCtx::getInstance()->appEngine()->rootContext()->setContextProperty("debugStates", QVariant::fromValue(wStates)); ApplicationCtx::getInstance()->appEngine()->rootContext()->setContextProperty("humanReadableExecutionCode", QVariant::fromValue(std::get<0>(code))); ApplicationCtx::getInstance()->appEngine()->rootContext()->setContextProperty("bytesCodeMapping", QVariant::fromValue(std::get<1>(code))); diff --git a/mix/AssemblyDebuggerModel.cpp b/mix/AssemblyDebuggerModel.cpp index c65beac7d..df027acf7 100644 --- a/mix/AssemblyDebuggerModel.cpp +++ b/mix/AssemblyDebuggerModel.cpp @@ -78,7 +78,6 @@ DebuggingContent AssemblyDebuggerModel::getContractInitiationDebugStates(dev::by return d; } - DebuggingContent AssemblyDebuggerModel::getContractInitiationDebugStates(dev::u256 _value, dev::u256 _gasPrice, dev::u256 _gas, diff --git a/mix/AssemblyDebuggerModel.h b/mix/AssemblyDebuggerModel.h index 3cac98db0..378f238e6 100644 --- a/mix/AssemblyDebuggerModel.h +++ b/mix/AssemblyDebuggerModel.h @@ -25,6 +25,7 @@ #include "libethereum/Executive.h" #include "libdevcore/Common.h" #include "DebuggingStateWrapper.h" + namespace dev { diff --git a/mix/CodeEditorExtensionManager.cpp b/mix/CodeEditorExtensionManager.cpp index c85292f2b..503e07447 100644 --- a/mix/CodeEditorExtensionManager.cpp +++ b/mix/CodeEditorExtensionManager.cpp @@ -64,15 +64,15 @@ void CodeEditorExtensionManager::initExtensions() initExtension(std::make_shared(m_doc)); } -void CodeEditorExtensionManager::initExtension(std::shared_ptr ext) +void CodeEditorExtensionManager::initExtension(std::shared_ptr _ext) { - if (!ext.get()->contentUrl().isEmpty()) + if (!_ext.get()->contentUrl().isEmpty()) { try { - if (ext.get()->getDisplayBehavior() == ExtensionDisplayBehavior::Tab) + if (_ext.get()->getDisplayBehavior() == ExtensionDisplayBehavior::Tab) { - ext.get()->addTabOn(m_tabView); + _ext.get()->addTabOn(m_tabView); } } catch (...) @@ -81,8 +81,8 @@ void CodeEditorExtensionManager::initExtension(std::shared_ptr ext) return; } } - ext.get()->start(); - m_features.append(ext); + _ext.get()->start(); + m_features.append(_ext); } void CodeEditorExtensionManager::setEditor(QQuickItem* _editor) diff --git a/mix/ConstantCompilationModel.h b/mix/ConstantCompilationModel.h index 01ad32224..713c9e950 100644 --- a/mix/ConstantCompilationModel.h +++ b/mix/ConstantCompilationModel.h @@ -45,7 +45,7 @@ class ConstantCompilationModel public: ConstantCompilationModel() {} ~ConstantCompilationModel() {} - CompilerResult compile(QString code); + CompilerResult compile(QString); }; } diff --git a/mix/DebuggingStateWrapper.cpp b/mix/DebuggingStateWrapper.cpp index 877598ca5..3bce8658b 100644 --- a/mix/DebuggingStateWrapper.cpp +++ b/mix/DebuggingStateWrapper.cpp @@ -31,7 +31,7 @@ using namespace dev; using namespace dev::eth; using namespace dev::mix; -std::tuple, QQMLMap*> DebuggingStateWrapper::getHumanReadableCode(const bytes& code) +std::tuple, QQMLMap*> DebuggingStateWrapper::getHumanReadableCode(const bytes& code, QObject* _objUsedAsParent) { QList codeStr; QMap codeMapping; @@ -51,7 +51,7 @@ std::tuple, QQMLMap*> DebuggingStateWrapper::getHumanReadableCod s = "PUSH 0x" + QString::fromStdString(toHex(bytesConstRef(&code[i + 1], bc))); i += bc; } - HumanReadableCode* humanCode = new HumanReadableCode(QString::fromStdString(out.str()) + " " + s, line); + HumanReadableCode* humanCode = new HumanReadableCode(QString::fromStdString(out.str()) + " " + s, line, _objUsedAsParent); codeStr.append(humanCode); } catch (...) @@ -61,7 +61,7 @@ std::tuple, QQMLMap*> DebuggingStateWrapper::getHumanReadableCod break; // probably hit data segment } } - return std::make_tuple(codeStr, new QQMLMap(codeMapping)); + return std::make_tuple(codeStr, new QQMLMap(codeMapping, _objUsedAsParent)); } QString DebuggingStateWrapper::debugStack() diff --git a/mix/DebuggingStateWrapper.h b/mix/DebuggingStateWrapper.h index 07716e9ad..0285a4693 100644 --- a/mix/DebuggingStateWrapper.h +++ b/mix/DebuggingStateWrapper.h @@ -65,7 +65,7 @@ class HumanReadableCode: public QObject Q_PROPERTY(int processIndex READ processIndex) public: - HumanReadableCode(QString _line, int _processIndex) : m_line(_line), m_processIndex(_processIndex) {} + HumanReadableCode(QString _line, int _processIndex, QObject* _parent) : m_line(_line), m_processIndex(_processIndex), QObject(_parent) {} QString line() { return m_line; } int processIndex() { return m_processIndex; } @@ -80,7 +80,7 @@ class QQMLMap : public QObject Q_OBJECT public: - QQMLMap(QMap _map) : m_map(_map) { } + QQMLMap(QMap _map, QObject* _parent) : m_map(_map), QObject(_parent) { } Q_INVOKABLE int getValue(int _key) { return m_map.value(_key); } private: @@ -118,7 +118,7 @@ public: QStringList levels(); DebuggingState state() { return m_state; } void setState(DebuggingState _state) { m_state = _state; } - static std::tuple, QQMLMap*> getHumanReadableCode(bytes const& code); + static std::tuple, QQMLMap*> getHumanReadableCode(bytes const& code, QObject* _objUsedAsParent); private: DebuggingState m_state; diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml index 490f49f61..6802f57df 100644 --- a/mix/qml/Debugger.qml +++ b/mix/qml/Debugger.qml @@ -84,7 +84,7 @@ Rectangle { anchors.top: statesList.bottom height: parent.height * 0.35 width: parent.width - anchors.topMargin: 13 + anchors.topMargin: 15 color: "transparent" Label { id: callStackLabel From 827de531b9f2f6d68c7ebbb40ed201d1f46a713b Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 5 Dec 2014 13:07:42 +0100 Subject: [PATCH 067/277] - Coding standards --- mix/AssemblyDebuggerModel.cpp | 4 ++-- mix/AssemblyDebuggerModel.h | 2 +- mix/CodeEditorExtensionManager.cpp | 1 - mix/DebuggingStateWrapper.cpp | 8 ++++---- mix/MixApplication.cpp | 2 +- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/mix/AssemblyDebuggerModel.cpp b/mix/AssemblyDebuggerModel.cpp index df027acf7..e4c2396ca 100644 --- a/mix/AssemblyDebuggerModel.cpp +++ b/mix/AssemblyDebuggerModel.cpp @@ -102,9 +102,9 @@ DebuggingContent AssemblyDebuggerModel::getContractInitiationDebugStates(dev::u2 return getContractInitiationDebugStates(bytesRef); } -bool AssemblyDebuggerModel::compile(QString code) +bool AssemblyDebuggerModel::compile(QString _code) { ConstantCompilationModel compiler; - CompilerResult res = compiler.compile(code); + CompilerResult res = compiler.compile(_code); return res.success; } diff --git a/mix/AssemblyDebuggerModel.h b/mix/AssemblyDebuggerModel.h index 378f238e6..c0941dc8f 100644 --- a/mix/AssemblyDebuggerModel.h +++ b/mix/AssemblyDebuggerModel.h @@ -38,7 +38,7 @@ public: AssemblyDebuggerModel(); DebuggingContent getContractInitiationDebugStates(dev::u256, dev::u256, dev::u256, QString, KeyPair); DebuggingContent getContractInitiationDebugStates(dev::bytesConstRef); - bool compile(QString code); + bool compile(QString); private: std::unique_ptr m_currentExecution; diff --git a/mix/CodeEditorExtensionManager.cpp b/mix/CodeEditorExtensionManager.cpp index 503e07447..3bef1a828 100644 --- a/mix/CodeEditorExtensionManager.cpp +++ b/mix/CodeEditorExtensionManager.cpp @@ -28,7 +28,6 @@ #include #include "ConstantCompilationCtrl.h" #include "AssemblyDebuggerCtrl.h" -#include "features.h" #include "ApplicationCtx.h" #include "CodeEditorExtensionManager.h" using namespace dev::mix; diff --git a/mix/DebuggingStateWrapper.cpp b/mix/DebuggingStateWrapper.cpp index 3bce8658b..d96c975cd 100644 --- a/mix/DebuggingStateWrapper.cpp +++ b/mix/DebuggingStateWrapper.cpp @@ -31,13 +31,13 @@ using namespace dev; using namespace dev::eth; using namespace dev::mix; -std::tuple, QQMLMap*> DebuggingStateWrapper::getHumanReadableCode(const bytes& code, QObject* _objUsedAsParent) +std::tuple, QQMLMap*> DebuggingStateWrapper::getHumanReadableCode(const bytes& _code, QObject* _objUsedAsParent) { QList codeStr; QMap codeMapping; - for (unsigned i = 0; i <= code.size(); ++i) + for (unsigned i = 0; i <= _code.size(); ++i) { - byte b = i < code.size() ? code[i] : 0; + byte b = i < _code.size() ? _code[i] : 0; try { QString s = QString::fromStdString(instructionInfo((Instruction)b).name); @@ -48,7 +48,7 @@ std::tuple, QQMLMap*> DebuggingStateWrapper::getHumanReadableCod if (b >= (byte)Instruction::PUSH1 && b <= (byte)Instruction::PUSH32) { unsigned bc = b - (byte)Instruction::PUSH1 + 1; - s = "PUSH 0x" + QString::fromStdString(toHex(bytesConstRef(&code[i + 1], bc))); + s = "PUSH 0x" + QString::fromStdString(toHex(bytesConstRef(&_code[i + 1], bc))); i += bc; } HumanReadableCode* humanCode = new HumanReadableCode(QString::fromStdString(out.str()) + " " + s, line, _objUsedAsParent); diff --git a/mix/MixApplication.cpp b/mix/MixApplication.cpp index e67ca1b12..86507329c 100644 --- a/mix/MixApplication.cpp +++ b/mix/MixApplication.cpp @@ -23,7 +23,7 @@ #include "MixApplication.h" using namespace dev::mix; -MixApplication::MixApplication(int _argc, char *_argv[]): QApplication(_argc, _argv) +MixApplication::MixApplication(int _argc, char* _argv[]): QApplication(_argc, _argv) { } From 85fa520d1b8b9487a28b176cd774d404ccee3b56 Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 5 Dec 2014 13:17:37 +0100 Subject: [PATCH 068/277] - Coding Standards --- mix/DebuggingStateWrapper.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mix/DebuggingStateWrapper.h b/mix/DebuggingStateWrapper.h index 0285a4693..3f03004b8 100644 --- a/mix/DebuggingStateWrapper.h +++ b/mix/DebuggingStateWrapper.h @@ -65,7 +65,7 @@ class HumanReadableCode: public QObject Q_PROPERTY(int processIndex READ processIndex) public: - HumanReadableCode(QString _line, int _processIndex, QObject* _parent) : m_line(_line), m_processIndex(_processIndex), QObject(_parent) {} + HumanReadableCode(QString _line, int _processIndex, QObject* _parent): QObject(_parent), m_line(_line), m_processIndex(_processIndex) {} QString line() { return m_line; } int processIndex() { return m_processIndex; } @@ -75,12 +75,12 @@ private: }; /* used to publish QMap type to QML */ -class QQMLMap : public QObject +class QQMLMap: public QObject { Q_OBJECT public: - QQMLMap(QMap _map, QObject* _parent) : m_map(_map), QObject(_parent) { } + QQMLMap(QMap _map, QObject* _parent): QObject(_parent), m_map(_map) { } Q_INVOKABLE int getValue(int _key) { return m_map.value(_key); } private: @@ -88,7 +88,7 @@ private: }; /* used to publish DebuggingState struct to QML */ -class DebuggingStateWrapper : public QObject +class DebuggingStateWrapper: public QObject { Q_OBJECT Q_PROPERTY(int step READ step) From fc8cb6d7af537e6e858ff3fa34f2dc5afc03f57b Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 5 Dec 2014 13:54:30 +0100 Subject: [PATCH 069/277] boost compatibility changes in msvc --- cmake/EthDependencies.cmake | 17 +++++++++++++++++ libdevcore/CMakeLists.txt | 12 +++++------- libdevcore/CommonData.cpp | 16 ++++++++++++++-- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index ae2483cda..223c14ce3 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -53,6 +53,23 @@ set(Boost_COMPILER -vc120) find_package(Boost 1.55.0 REQUIRED COMPONENTS thread date_time system regex) +if (Boost_FOUND) + message(" - boost header: ${Boost_INCLUDE_DIRS}") + message(" - boost lib : ${Boost_LIBRARIES}") +endif() + + + + + + + + + + + + + diff --git a/libdevcore/CMakeLists.txt b/libdevcore/CMakeLists.txt index 3ff0733b4..5bcff1ead 100644 --- a/libdevcore/CMakeLists.txt +++ b/libdevcore/CMakeLists.txt @@ -5,8 +5,9 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) -include_directories(${LEVELDB_INCLUDE_DIR}) include_directories(..) +include_directories(${LEVELDB_INCLUDE_DIR}) +include_directories(${Boost_INCLUDE_DIRS}) set(EXECUTABLE devcore) @@ -18,16 +19,13 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() +target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY}) + if (APPLE) - # Latest mavericks boost libraries only come with -mt - target_link_libraries(${EXECUTABLE} boost_system-mt) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt) - target_link_libraries(${EXECUTABLE} boost_thread-mt) find_package(Threads REQUIRED) target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) elseif (UNIX) - find_package(Boost 1.53 REQUIRED COMPONENTS thread system) - target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY} ${Boost_SYSTEM_LIBRARY}) find_package(Threads REQUIRED) target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) endif() diff --git a/libdevcore/CommonData.cpp b/libdevcore/CommonData.cpp index d34b565eb..215f9c4b3 100644 --- a/libdevcore/CommonData.cpp +++ b/libdevcore/CommonData.cpp @@ -89,13 +89,25 @@ bytes dev::fromHex(std::string const& _s) { ret.push_back(fromHex(_s[s++])); } - catch (...){ ret.push_back(0); cwarn << boost::current_exception_diagnostic_information(); } + catch (...) + { + ret.push_back(0); + // msvc does not support it +#ifndef BOOST_NO_EXCEPTIONS + cwarn << boost::current_exception_diagnostic_information(); +#endif + } for (unsigned i = s; i < _s.size(); i += 2) try { ret.push_back((byte)(fromHex(_s[i]) * 16 + fromHex(_s[i + 1]))); } - catch (...){ ret.push_back(0); cwarn << boost::current_exception_diagnostic_information(); } + catch (...){ + ret.push_back(0); +#ifndef BOOST_NO_EXCEPTIONS + cwarn << boost::current_exception_diagnostic_information(); +#endif + } return ret; } From bb3a0bc0e43d83fc71bcc44721e561ac98cdfc27 Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 5 Dec 2014 15:25:31 +0100 Subject: [PATCH 070/277] devcore, evmcore, jsqrc compiling on windows --- cmake/EthCompilerSettings.cmake | 63 +++++++++++++++++---------------- libdevcore/CMakeLists.txt | 2 +- libdevcore/RLP.h | 8 ++--- libevmcore/CMakeLists.txt | 5 +-- libevmcore/Instruction.cpp | 4 +++ libjsqrc/CMakeLists.txt | 16 --------- 6 files changed, 44 insertions(+), 54 deletions(-) diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index 2757eb9ad..60ea3c90f 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -12,7 +12,8 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") - set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -DSHAREDLIB") + set(CMAKE_CXX_FLAGS "") + set(ETH_STATIC 1) else () message(FATAL_ERROR "Your C++ compiler does not support C++11. You have ${CMAKE_CXX_COMPILER_ID}") endif () @@ -27,36 +28,36 @@ set(CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG -DETH_RELEASE") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_DEBUG") # Windows -if ("${TARGET_PLATFORM}" STREQUAL "w64") - set(CMAKE_SYSTEM_NAME Windows) - - set(CMAKE_CXX_LIBRARY_ARCHITECTURE x86_64-w64-mingw32) - set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) - set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) - set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) - set(CMAKE_AR x86_64-w64-mingw32-ar) - set(CMAKE_RANLIB x86_64-w64-mingw32-ranlib) - - set(CMAKE_EXECUTABLE_SUFFIX .exe) - - set(CMAKE_FIND_ROOT_PATH - /usr/x86_64-w64-mingw32 - ) - - include_directories(/usr/x86_64-w64-mingw32/include/cryptopp) - - set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) - set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) - set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) - - set(CMAKE_INSTALL_PREFIX /usr/x86_64-w64-mingw32) - set(ETH_BUILD_PLATFORM "windows") - set(ETH_STATIC 1) -else () - set(ETH_BUILD_PLATFORM ${CMAKE_SYSTEM_NAME}) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") - set(ETH_SHARED 1) -endif() +#if ("${TARGET_PLATFORM}" STREQUAL "w64") +# set(CMAKE_SYSTEM_NAME Windows) +# +# set(CMAKE_CXX_LIBRARY_ARCHITECTURE x86_64-w64-mingw32) +# set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) +# set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) +# set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) +# set(CMAKE_AR x86_64-w64-mingw32-ar) +# set(CMAKE_RANLIB x86_64-w64-mingw32-ranlib) +# +# set(CMAKE_EXECUTABLE_SUFFIX .exe) +# +# set(CMAKE_FIND_ROOT_PATH +# /usr/x86_64-w64-mingw32 +# ) +# +# include_directories(/usr/x86_64-w64-mingw32/include/cryptopp) +# +# set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +# set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +# set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +# +# set(CMAKE_INSTALL_PREFIX /usr/x86_64-w64-mingw32) +# set(ETH_BUILD_PLATFORM "windows") +# set(ETH_STATIC 1) +#else () +# set(ETH_BUILD_PLATFORM ${CMAKE_SYSTEM_NAME}) +# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") +# set(ETH_SHARED 1) +#endif() diff --git a/libdevcore/CMakeLists.txt b/libdevcore/CMakeLists.txt index 5bcff1ead..c6f3b735d 100644 --- a/libdevcore/CMakeLists.txt +++ b/libdevcore/CMakeLists.txt @@ -19,8 +19,8 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) if (APPLE) find_package(Threads REQUIRED) diff --git a/libdevcore/RLP.h b/libdevcore/RLP.h index 3101f63d6..2eedbaba2 100644 --- a/libdevcore/RLP.h +++ b/libdevcore/RLP.h @@ -28,10 +28,10 @@ #include #include #include -#include -#include -#include -#include +#include "vector_ref.h" +#include "Common.h" +#include "Exceptions.h" +#include "FixedHash.h" namespace dev { diff --git a/libevmcore/CMakeLists.txt b/libevmcore/CMakeLists.txt index b889e7163..472e112a1 100644 --- a/libevmcore/CMakeLists.txt +++ b/libevmcore/CMakeLists.txt @@ -5,6 +5,9 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) +include_directories(..) +include_directories(${Boost_INCLUDE_DIRS}) + set(EXECUTABLE evmcore) file(GLOB HEADERS "*.h") @@ -14,8 +17,6 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -include_directories(..) - target_link_libraries(${EXECUTABLE} devcore) install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) diff --git a/libevmcore/Instruction.cpp b/libevmcore/Instruction.cpp index 9062fd8ed..b4a4d9f3b 100644 --- a/libevmcore/Instruction.cpp +++ b/libevmcore/Instruction.cpp @@ -326,7 +326,11 @@ InstructionInfo dev::eth::instructionInfo(Instruction _inst) } catch (...) { +#ifndef BOOST_NO_EXCEPTIONS cwarn << "\n" << boost::current_exception_diagnostic_information(); +#else + cwarn << "\n"; +#endif return InstructionInfo({"", 0, 0, 0, false}); } } diff --git a/libjsqrc/CMakeLists.txt b/libjsqrc/CMakeLists.txt index 9c505df2b..b8beec2ff 100644 --- a/libjsqrc/CMakeLists.txt +++ b/libjsqrc/CMakeLists.txt @@ -1,20 +1,4 @@ cmake_policy(SET CMP0015 NEW) - -# Find Qt5 for Apple and update src_list for windows -if (APPLE) - # homebrew defaults to qt4 and installs qt5 as 'keg-only' - # which places it into /usr/local/opt insteadof /usr/local. - - set(CMAKE_PREFIX_PATH /usr/local/opt/qt5) - include_directories(/usr/local/opt/qt5/include /usr/local/include) -elseif ("${TARGET_PLATFORM}" STREQUAL "w64") - set(SRC_LIST ${SRC_LIST} ../windows/qt_plugin_import.cpp) -elseif (UNIX) - set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ";$ENV{QTDIR}/lib/cmake") -endif () - -find_package(Qt5Core) - set(CMAKE_AUTOMOC OFF) qt5_add_resources(JSQRC js.qrc) From eb3e005dee2b03a2fa43b4d806338996a4586d97 Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 5 Dec 2014 16:20:00 +0100 Subject: [PATCH 071/277] use unique_ptr for QQMLApplicationEngine --- mix/ApplicationCtx.cpp | 11 +++-------- mix/ApplicationCtx.h | 4 ++-- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/mix/ApplicationCtx.cpp b/mix/ApplicationCtx.cpp index 99d9bee4c..0130f2dfb 100644 --- a/mix/ApplicationCtx.cpp +++ b/mix/ApplicationCtx.cpp @@ -37,19 +37,14 @@ ApplicationCtx* ApplicationCtx::Instance = nullptr; ApplicationCtx::ApplicationCtx(QQmlApplicationEngine* _engine) { - m_applicationEngine = _engine; + m_applicationEngine = std::unique_ptr(_engine); m_keyEventManager = std::unique_ptr(new KeyEventManager()); m_webThree = std::unique_ptr(new WebThreeDirect(std::string("Mix/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir() + "/Mix", false, {"eth", "shh"})); } -ApplicationCtx::~ApplicationCtx() -{ - delete m_applicationEngine; -} - QQmlApplicationEngine* ApplicationCtx::appEngine() { - return m_applicationEngine; + return m_applicationEngine.get(); } dev::eth::Client* ApplicationCtx::getEthereumClient() @@ -81,7 +76,7 @@ void ApplicationCtx::setApplicationContext(QQmlApplicationEngine* _engine) void ApplicationCtx::displayMessageDialog(QString _title, QString _message) { - QQmlComponent component(m_applicationEngine, QUrl("qrc:/qml/BasicMessage.qml")); + QQmlComponent component(m_applicationEngine.get(), QUrl("qrc:/qml/BasicMessage.qml")); QObject* dialog = component.create(); dialog->findChild("messageContent", Qt::FindChildrenRecursively)->setProperty("text", _message); QObject* dialogWin = ApplicationCtx::getInstance()->appEngine()->rootObjects().at(0)->findChild("messageDialog", Qt::FindChildrenRecursively); diff --git a/mix/ApplicationCtx.h b/mix/ApplicationCtx.h index 05e4f3bb3..5680c860e 100644 --- a/mix/ApplicationCtx.h +++ b/mix/ApplicationCtx.h @@ -42,7 +42,7 @@ class ApplicationCtx: public QObject public: ApplicationCtx(QQmlApplicationEngine* _engine); - ~ApplicationCtx(); + ~ApplicationCtx() {} static ApplicationCtx* getInstance() { return Instance; } static void setApplicationContext(QQmlApplicationEngine* _engine); QQmlApplicationEngine* appEngine(); @@ -53,7 +53,7 @@ public: private: static ApplicationCtx* Instance; - QQmlApplicationEngine* m_applicationEngine; + std::unique_ptr m_applicationEngine; std::unique_ptr m_webThree; std::unique_ptr m_keyEventManager; From 9d59ee4aa18597f8b02381f03f6f1429b9c2dc3d Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 5 Dec 2014 16:40:41 +0100 Subject: [PATCH 072/277] lll, buildinfo.h and llc compiling on windows --- CMakeLists.txt | 11 +++++++++-- libdevcore/CMakeLists.txt | 2 +- libevmcore/CMakeLists.txt | 2 +- liblll/CMakeLists.txt | 30 +++--------------------------- lllc/CMakeLists.txt | 25 ++++++++----------------- 5 files changed, 22 insertions(+), 48 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8fc718297..d4be26923 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,7 +51,7 @@ function(createBuildInfo) set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/msys") elseif (CMAKE_COMPILER_IS_GNUCXX) set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/g++") - elseif (CMAKE_COMPILER_IS_MSVC) + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/msvc") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/clang") @@ -59,8 +59,15 @@ function(createBuildInfo) set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/unknown") endif () + #cmake build type may be not specified when using msvc + if (${CMAKE_BUILD_TYPE}) + set(_cmake_build_type ${CMAKE_BUILD_TYPE}) + else() + set(_cmake_build_type "undefined") + endif() + # Generate header file containing useful build information - add_custom_target(BuildInfo.h ALL COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/BuildInfo.sh ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BUILD_TYPE} ${ETH_BUILD_PLATFORM}) + add_custom_target(BuildInfo.h ALL COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/BuildInfo.sh ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${_cmake_build_type} ${ETH_BUILD_PLATFORM}) include_directories(${CMAKE_CURRENT_BINARY_DIR}) set(CMAKE_INCLUDE_CURRENT_DIR ON) diff --git a/libdevcore/CMakeLists.txt b/libdevcore/CMakeLists.txt index c6f3b735d..3d103160c 100644 --- a/libdevcore/CMakeLists.txt +++ b/libdevcore/CMakeLists.txt @@ -5,9 +5,9 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) -include_directories(..) include_directories(${LEVELDB_INCLUDE_DIR}) include_directories(${Boost_INCLUDE_DIRS}) +include_directories(..) set(EXECUTABLE devcore) diff --git a/libevmcore/CMakeLists.txt b/libevmcore/CMakeLists.txt index 472e112a1..0f71dcd40 100644 --- a/libevmcore/CMakeLists.txt +++ b/libevmcore/CMakeLists.txt @@ -5,8 +5,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) -include_directories(..) include_directories(${Boost_INCLUDE_DIRS}) +include_directories(..) set(EXECUTABLE evmcore) diff --git a/liblll/CMakeLists.txt b/liblll/CMakeLists.txt index 4e6941359..e2c000010 100644 --- a/liblll/CMakeLists.txt +++ b/liblll/CMakeLists.txt @@ -5,6 +5,9 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) +include_directories(${Boost_INCLUDE_DIRS}) +include_directories(..) + set(EXECUTABLE lll) file(GLOB HEADERS "*.h") @@ -14,36 +17,9 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -include_directories(..) - target_link_libraries(${EXECUTABLE} evmcore) target_link_libraries(${EXECUTABLE} devcore) - -if("${TARGET_PLATFORM}" STREQUAL "w64") - target_link_libraries(${EXECUTABLE} boost_system-mt-s) - target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) - target_link_libraries(${EXECUTABLE} iphlpapi) - target_link_libraries(${EXECUTABLE} ws2_32) - target_link_libraries(${EXECUTABLE} mswsock) - target_link_libraries(${EXECUTABLE} shlwapi) -elseif (APPLE) - # Latest mavericks boost libraries only come with -mt - target_link_libraries(${EXECUTABLE} boost_system-mt) - target_link_libraries(${EXECUTABLE} boost_thread-mt) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -elseif (UNIX) - target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -else () - target_link_libraries(${EXECUTABLE} boost_system) - target_link_libraries(${EXECUTABLE} boost_thread) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -endif () - install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/lllc/CMakeLists.txt b/lllc/CMakeLists.txt index 3310354fb..0ca19fab9 100644 --- a/lllc/CMakeLists.txt +++ b/lllc/CMakeLists.txt @@ -3,31 +3,22 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) +include_directories(${Boost_INCLUDE_DIRS}) include_directories(..) set(EXECUTABLE lllc) -add_executable(${EXECUTABLE} ${SRC_LIST}) +if(ETH_STATIC) + add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS}) +else() + add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) +endif() + +add_dependencies(${EXECUTABLE} BuildInfo.h) target_link_libraries(${EXECUTABLE} lll) target_link_libraries(${EXECUTABLE} evmcore) target_link_libraries(${EXECUTABLE} devcore) -if ("${TARGET_PLATFORM}" STREQUAL "w64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") - target_link_libraries(${EXECUTABLE} gcc) - target_link_libraries(${EXECUTABLE} gdi32) - target_link_libraries(${EXECUTABLE} ws2_32) - target_link_libraries(${EXECUTABLE} mswsock) - target_link_libraries(${EXECUTABLE} shlwapi) - target_link_libraries(${EXECUTABLE} iphlpapi) - target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) - set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) -elseif (UNIX) -else () - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -endif () - install( TARGETS ${EXECUTABLE} DESTINATION bin ) From 5063433df42fca47566a78625334cf3ff9f03114 Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 5 Dec 2014 17:00:26 +0100 Subject: [PATCH 073/277] solidity compiling on windows, fixed Compiler Error C2797 --- libsolidity/CMakeLists.txt | 5 +++-- libsolidity/GlobalContext.cpp | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index 260493b0e..8522130ee 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -5,6 +5,9 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) +include_directories(${Boost_INCLUDE_DIRS}) +include_directories(..) + set(EXECUTABLE solidity) file(GLOB HEADERS "*.h") @@ -14,8 +17,6 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -include_directories(..) - target_link_libraries(${EXECUTABLE} evmcore devcore) install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) diff --git a/libsolidity/GlobalContext.cpp b/libsolidity/GlobalContext.cpp index d8b637076..b54b93c03 100644 --- a/libsolidity/GlobalContext.cpp +++ b/libsolidity/GlobalContext.cpp @@ -33,7 +33,7 @@ namespace solidity { GlobalContext::GlobalContext(): - m_magicVariables{make_shared("block", make_shared(MagicType::Kind::BLOCK)), +m_magicVariables(vector>{make_shared("block", make_shared(MagicType::Kind::BLOCK)), make_shared("msg", make_shared(MagicType::Kind::MSG)), make_shared("tx", make_shared(MagicType::Kind::TX)), make_shared("suicide", @@ -59,7 +59,7 @@ GlobalContext::GlobalContext(): make_shared("ripemd160", make_shared(TypePointers({std::make_shared(256, IntegerType::Modifier::HASH)}), TypePointers({std::make_shared(160, IntegerType::Modifier::HASH)}), - FunctionType::Location::RIPEMD160))} + FunctionType::Location::RIPEMD160))}) { } From f97826d07147ccab522220e84f5259867cfc8e87 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 4 Dec 2014 17:55:04 +0100 Subject: [PATCH 074/277] fix stackoverflow in calldataload, codecopy, extcodecopy + some tests --- libevm/VM.h | 40 +++---- test/stPreCompiledContractsFiller.json | 35 ++++++ test/vm.cpp | 20 ++++ test/vmEnvironmentalInfoTestFiller.json | 140 ++++++++++++++++++++++++ 4 files changed, 215 insertions(+), 20 deletions(-) diff --git a/libevm/VM.h b/libevm/VM.h index 5fb46fc68..0e27db02d 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -524,12 +524,12 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con break; case Instruction::CALLDATALOAD: { - if ((unsigned)m_stack.back() + 31 < _ext.data.size()) + if ((unsigned)m_stack.back() + (uint64_t)31 < _ext.data.size()) m_stack.back() = (u256)*(h256 const*)(_ext.data.data() + (unsigned)m_stack.back()); else { h256 r; - for (unsigned i = (unsigned)m_stack.back(), e = (unsigned)m_stack.back() + 32, j = 0; i < e; ++i, ++j) + for (uint64_t i = (unsigned)m_stack.back(), e = (unsigned)m_stack.back() + 32, j = 0; i < e; ++i, ++j) r[j] = i < _ext.data.size() ? _ext.data[i] : 0; m_stack.back() = (u256)r; } @@ -540,15 +540,15 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con break; case Instruction::CALLDATACOPY: { - unsigned mf = (unsigned)m_stack.back(); + unsigned offset = (unsigned)m_stack.back(); m_stack.pop_back(); - u256 cf = m_stack.back(); + u256 dataIndex = m_stack.back(); m_stack.pop_back(); - unsigned l = (unsigned)m_stack.back(); + unsigned size = (unsigned)m_stack.back(); m_stack.pop_back(); - unsigned el = cf + l > (u256)_ext.data.size() ? (u256)_ext.data.size() < cf ? 0 : _ext.data.size() - (unsigned)cf : l; - memcpy(m_temp.data() + mf, _ext.data.data() + (unsigned)cf, el); - memset(m_temp.data() + mf + el, 0, l - el); + unsigned el = dataIndex + (bigint)size > (u256)_ext.data.size() ? (u256)_ext.data.size() < dataIndex ? 0 : _ext.data.size() - (unsigned)dataIndex : size; + memcpy(m_temp.data() + offset, _ext.data.data() + (unsigned)dataIndex, el); + memset(m_temp.data() + offset + el, 0, size - el); break; } case Instruction::CODESIZE: @@ -556,15 +556,15 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con break; case Instruction::CODECOPY: { - unsigned mf = (unsigned)m_stack.back(); + unsigned offset = (unsigned)m_stack.back(); m_stack.pop_back(); - u256 cf = (u256)m_stack.back(); + u256 dataIndex = (u256)m_stack.back(); m_stack.pop_back(); - unsigned l = (unsigned)m_stack.back(); + unsigned size = (unsigned)m_stack.back(); m_stack.pop_back(); - unsigned el = cf + l > (u256)_ext.code.size() ? (u256)_ext.code.size() < cf ? 0 : _ext.code.size() - (unsigned)cf : l; - memcpy(m_temp.data() + mf, _ext.code.data() + (unsigned)cf, el); - memset(m_temp.data() + mf + el, 0, l - el); + unsigned el = dataIndex + (bigint)size > (u256)_ext.code.size() ? (u256)_ext.code.size() < dataIndex ? 0 : _ext.code.size() - (unsigned)dataIndex : size; + memcpy(m_temp.data() + offset, _ext.code.data() + (unsigned)dataIndex, el); + memset(m_temp.data() + offset + el, 0, size - el); break; } case Instruction::EXTCODESIZE: @@ -574,15 +574,15 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con { Address a = asAddress(m_stack.back()); m_stack.pop_back(); - unsigned mf = (unsigned)m_stack.back(); + unsigned offset = (unsigned)m_stack.back(); m_stack.pop_back(); - u256 cf = m_stack.back(); + u256 dataIndex = m_stack.back(); m_stack.pop_back(); - unsigned l = (unsigned)m_stack.back(); + unsigned size = (unsigned)m_stack.back(); m_stack.pop_back(); - unsigned el = cf + l > (u256)_ext.codeAt(a).size() ? (u256)_ext.codeAt(a).size() < cf ? 0 : _ext.codeAt(a).size() - (unsigned)cf : l; - memcpy(m_temp.data() + mf, _ext.codeAt(a).data() + (unsigned)cf, el); - memset(m_temp.data() + mf + el, 0, l - el); + unsigned el = dataIndex + (bigint)size > (u256)_ext.codeAt(a).size() ? (u256)_ext.codeAt(a).size() < dataIndex ? 0 : _ext.codeAt(a).size() - (unsigned)dataIndex : size; + memcpy(m_temp.data() + offset, _ext.codeAt(a).data() + (unsigned)dataIndex, el); + memset(m_temp.data() + offset + el, 0, size - el); break; } case Instruction::GASPRICE: diff --git a/test/stPreCompiledContractsFiller.json b/test/stPreCompiledContractsFiller.json index 9c65ad37b..62a3a1623 100644 --- a/test/stPreCompiledContractsFiller.json +++ b/test/stPreCompiledContractsFiller.json @@ -33,6 +33,41 @@ } }, + "CallEcrecover0_overlappingInputOutput": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : 0, + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 1000 1 0 0 128 64 32) [[ 0 ]] (MOD (MLOAD 64) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CallEcrecover0_completeReturnValue": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", diff --git a/test/vm.cpp b/test/vm.cpp index d7bc0612a..e674d6de3 100644 --- a/test/vm.cpp +++ b/test/vm.cpp @@ -488,6 +488,26 @@ BOOST_AUTO_TEST_CASE(vmLogTest) dev::test::executeTests("vmLogTest", "/VMTests", dev::test::doVMTests); } +BOOST_AUTO_TEST_CASE(vmPerformanceTest) +{ + for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) + { + string arg = boost::unit_test::framework::master_test_suite().argv[i]; + if (arg == "--performance") + dev::test::executeTests("vmPerformanceTest", "/VMTests", dev::test::doVMTests); + } +} + +BOOST_AUTO_TEST_CASE(vmArithPerformanceTest) +{ + for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) + { + string arg = boost::unit_test::framework::master_test_suite().argv[i]; + if (arg == "--performance") + dev::test::executeTests("vmArithPerformanceTest", "/VMTests", dev::test::doVMTests); + } +} + BOOST_AUTO_TEST_CASE(vmRandom) { string testPath = getTestPath(); diff --git a/test/vmEnvironmentalInfoTestFiller.json b/test/vmEnvironmentalInfoTestFiller.json index 95e7936aa..abeed9945 100644 --- a/test/vmEnvironmentalInfoTestFiller.json +++ b/test/vmEnvironmentalInfoTestFiller.json @@ -338,6 +338,33 @@ } }, + "calldataloadSizeTooHigh": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (CALLDATALOAD 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa)}", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "0x123456789abcdef0000000000000000000000000000000000000000000000000024", + "gasPrice" : "1000000000", + "gas" : "100000000000" + } + }, "calldatasize0": { "env" : { @@ -451,6 +478,62 @@ } }, + "calldatacopy_DataIndexTooHigh": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ (CALLDATACOPY 0 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa 0xff ) [[ 0 ]] @0}", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "0x1234567890abcdef01234567890abcdef", + "gasPrice" : "1000000000", + "gas" : "100000000000" + } + }, + + "calldatacopy_DataIndexTooHigh2": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ (CALLDATACOPY 0 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa 9 ) [[ 0 ]] @0}", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "0x1234567890abcdef01234567890abcdef", + "gasPrice" : "1000000000", + "gas" : "100000000000" + } + }, + "calldatacopy1": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", @@ -535,6 +618,34 @@ } }, + "codecopy_DataIndexTooHigh": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ (CODECOPY 0 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa 8 ) [[ 0 ]] @0}", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "0x1234567890abcdef01234567890abcdef", + "gasPrice" : "1000000000", + "gas" : "100000000000" + } + }, + "codecopy0": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", @@ -686,6 +797,35 @@ } }, + "extcodecopy_DataIndexTooHigh": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ (EXTCODECOPY (ADDRESS) 0 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa 8 ) [[ 0 ]] @0}", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "0x1234567890abcdef01234567890abcdef", + "gasPrice" : "1000000000", + "gas" : "100000000000" + } + }, + + "extcodecopy0": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", From 80f69b7383b24c4a9a27110b4f6cd4dcd0e311ea Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 4 Dec 2014 18:17:03 +0100 Subject: [PATCH 075/277] avoid code repetition in vm --- libevm/VM.h | 58 +++++++++++++++++++++++++---------------------------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/libevm/VM.h b/libevm/VM.h index 0e27db02d..d846ff079 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -538,50 +538,46 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con case Instruction::CALLDATASIZE: m_stack.push_back(_ext.data.size()); break; - case Instruction::CALLDATACOPY: - { - unsigned offset = (unsigned)m_stack.back(); - m_stack.pop_back(); - u256 dataIndex = m_stack.back(); - m_stack.pop_back(); - unsigned size = (unsigned)m_stack.back(); - m_stack.pop_back(); - unsigned el = dataIndex + (bigint)size > (u256)_ext.data.size() ? (u256)_ext.data.size() < dataIndex ? 0 : _ext.data.size() - (unsigned)dataIndex : size; - memcpy(m_temp.data() + offset, _ext.data.data() + (unsigned)dataIndex, el); - memset(m_temp.data() + offset + el, 0, size - el); - break; - } case Instruction::CODESIZE: m_stack.push_back(_ext.code.size()); break; - case Instruction::CODECOPY: - { - unsigned offset = (unsigned)m_stack.back(); - m_stack.pop_back(); - u256 dataIndex = (u256)m_stack.back(); - m_stack.pop_back(); - unsigned size = (unsigned)m_stack.back(); - m_stack.pop_back(); - unsigned el = dataIndex + (bigint)size > (u256)_ext.code.size() ? (u256)_ext.code.size() < dataIndex ? 0 : _ext.code.size() - (unsigned)dataIndex : size; - memcpy(m_temp.data() + offset, _ext.code.data() + (unsigned)dataIndex, el); - memset(m_temp.data() + offset + el, 0, size - el); - break; - } case Instruction::EXTCODESIZE: m_stack.back() = _ext.codeAt(asAddress(m_stack.back())).size(); break; + case Instruction::CALLDATACOPY: + case Instruction::CODECOPY: case Instruction::EXTCODECOPY: { - Address a = asAddress(m_stack.back()); - m_stack.pop_back(); + Address a; + if (inst == Instruction::EXTCODECOPY) + { + a = asAddress(m_stack.back()); + m_stack.pop_back(); + } unsigned offset = (unsigned)m_stack.back(); m_stack.pop_back(); - u256 dataIndex = m_stack.back(); + u256 index = m_stack.back(); m_stack.pop_back(); unsigned size = (unsigned)m_stack.back(); m_stack.pop_back(); - unsigned el = dataIndex + (bigint)size > (u256)_ext.codeAt(a).size() ? (u256)_ext.codeAt(a).size() < dataIndex ? 0 : _ext.codeAt(a).size() - (unsigned)dataIndex : size; - memcpy(m_temp.data() + offset, _ext.codeAt(a).data() + (unsigned)dataIndex, el); + unsigned el; + switch(inst) + { + case Instruction::CALLDATACOPY: + el = index + (bigint)size > (u256)_ext.data.size() ? (u256)_ext.data.size() < index ? 0 : _ext.data.size() - (unsigned)index : size; + memcpy(m_temp.data() + offset, _ext.data.data() + (unsigned)index, el); + break; + case Instruction::CODECOPY: + el = index + (bigint)size > (u256)_ext.code.size() ? (u256)_ext.code.size() < index ? 0 : _ext.code.size() - (unsigned)index : size; + memcpy(m_temp.data() + offset, _ext.code.data() + (unsigned)index, el); + break; + case Instruction::EXTCODECOPY: + el = index + (bigint)size > (u256)_ext.codeAt(a).size() ? (u256)_ext.codeAt(a).size() < index ? 0 : _ext.codeAt(a).size() - (unsigned)index : size; + memcpy(m_temp.data() + offset, _ext.codeAt(a).data() + (unsigned)index, el); + break; + default: + break; + } memset(m_temp.data() + offset + el, 0, size - el); break; } From 2d4d9c7485463d8d65e8a0898a35558d2a871221 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 4 Dec 2014 19:23:48 +0100 Subject: [PATCH 076/277] minor fix --- libevm/VM.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libevm/VM.h b/libevm/VM.h index d846ff079..f5feead40 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -529,7 +529,7 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con else { h256 r; - for (uint64_t i = (unsigned)m_stack.back(), e = (unsigned)m_stack.back() + 32, j = 0; i < e; ++i, ++j) + for (uint64_t i = (unsigned)m_stack.back(), e = (unsigned)m_stack.back() + (uint64_t)32, j = 0; i < e; ++i, ++j) r[j] = i < _ext.data.size() ? _ext.data[i] : 0; m_stack.back() = (u256)r; } From 86794daded9bd911883fcf190eb100f1331f6290 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Fri, 5 Dec 2014 11:34:30 +0100 Subject: [PATCH 077/277] even less code --- libevm/VM.h | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/libevm/VM.h b/libevm/VM.h index f5feead40..be64c0ad1 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -560,24 +560,23 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con m_stack.pop_back(); unsigned size = (unsigned)m_stack.back(); m_stack.pop_back(); - unsigned el; + bytes toBeCopied; switch(inst) { case Instruction::CALLDATACOPY: - el = index + (bigint)size > (u256)_ext.data.size() ? (u256)_ext.data.size() < index ? 0 : _ext.data.size() - (unsigned)index : size; - memcpy(m_temp.data() + offset, _ext.data.data() + (unsigned)index, el); + toBeCopied = _ext.data.toBytes(); break; case Instruction::CODECOPY: - el = index + (bigint)size > (u256)_ext.code.size() ? (u256)_ext.code.size() < index ? 0 : _ext.code.size() - (unsigned)index : size; - memcpy(m_temp.data() + offset, _ext.code.data() + (unsigned)index, el); + toBeCopied = _ext.code; break; case Instruction::EXTCODECOPY: - el = index + (bigint)size > (u256)_ext.codeAt(a).size() ? (u256)_ext.codeAt(a).size() < index ? 0 : _ext.codeAt(a).size() - (unsigned)index : size; - memcpy(m_temp.data() + offset, _ext.codeAt(a).data() + (unsigned)index, el); + toBeCopied = _ext.codeAt(a); break; default: break; } + unsigned el = index + (bigint)size > (u256)toBeCopied.size() ? (u256)toBeCopied.size() < index ? 0 : toBeCopied.size() - (unsigned)index : size; + memcpy(m_temp.data() + offset, toBeCopied.data() + (unsigned)index, el); memset(m_temp.data() + offset + el, 0, size - el); break; } From 548dda844a1dcb798ce708700571ff7423034ae5 Mon Sep 17 00:00:00 2001 From: debris Date: Sun, 7 Dec 2014 11:29:38 +0100 Subject: [PATCH 078/277] solidity compiling under msvc && boosts cmake file fixed --- extdep/CMakeLists.txt | 22 +++---- extdep/compile/boost.cmake | 19 ++++++ extdep/compile/configure.bat | 111 +++++++++++++++++++++++++++++++++ libsolidity/CMakeLists.txt | 9 ++- libsolidity/CompilerStack.h | 16 +++++ libsolidity/InterfaceHandler.h | 2 +- lllc/CMakeLists.txt | 8 +-- solc/CMakeLists.txt | 4 +- 8 files changed, 167 insertions(+), 24 deletions(-) create mode 100644 extdep/compile/boost.cmake create mode 100644 extdep/compile/configure.bat diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index cea32c80f..f57d6eac8 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -6,7 +6,7 @@ include(eth_download.cmake) # all dependencies will be installed into this directory, separated by platform string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name) -set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install/${_system_name}") +set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install2/${_system_name}") set(ETH_DEPENDENCY_SERVER "http://poc-7.ethdev.com/precompiled/${_system_name}") file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/lib) file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include) @@ -14,22 +14,22 @@ file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/bin) if (ETH_COMPILE) # json-rpc-cpp and its dependencies - include(compile/jsoncpp.cmake) - include(compile/argtable2.cmake) - include(compile/curl.cmake) - include(compile/json-rpc-cpp.cmake) + #include(compile/jsoncpp.cmake) + #include(compile/argtable2.cmake) + #include(compile/curl.cmake) + #include(compile/json-rpc-cpp.cmake) # qt at its dependencies - include(compile/icu.cmake) - include(compile/jom.cmake) - include(compile/qt.cmake) + #include(compile/icu.cmake) + #include(compile/jom.cmake) + #include(compile/qt.cmake) # leveldb and its dependencies - include(compile/snappy.cmake) - include(compile/leveldb.cmake) + #include(compile/snappy.cmake) + #include(compile/leveldb.cmake) # cryptopp - include(compile/cryptopp.cmake) + #include(compile/cryptopp.cmake) # boost include(compile/boost.cmake) diff --git a/extdep/compile/boost.cmake b/extdep/compile/boost.cmake new file mode 100644 index 000000000..aaf892cc9 --- /dev/null +++ b/extdep/compile/boost.cmake @@ -0,0 +1,19 @@ +if(APPLE) + +elseif(WIN32) +set(boost_address_model) +# on windows 64: +# set(boost_address_model address-model=64) + +set(boost_targets --with-filesystem --with-system --with-thread --with-date_time --with-regex --with-test) +ExternalProject_Add(boost + URL http://downloads.sourceforge.net/project/boost/boost/1.55.0/boost_1_55_0.tar.gz + BINARY_DIR boost-prefix/src/boost + CONFIGURE_COMMAND ./bootstrap.bat + BUILD_COMMAND ./b2.exe -j4 --build-type=complete link=static runtime-link=shared variant=debug,release threading=multi ${boost_addressModel} ${boost_targets} install --prefix=${ETH_DEPENDENCY_INSTALL_DIR} + INSTALL_COMMAND cmake -E rename ${ETH_DEPENDENCY_INSTALL_DIR}/include/boost-1_55/boost ${ETH_DEPENDENCY_INSTALL_DIR}/include/boost + ) +else() + +endif() + diff --git a/extdep/compile/configure.bat b/extdep/compile/configure.bat new file mode 100644 index 000000000..bd810938a --- /dev/null +++ b/extdep/compile/configure.bat @@ -0,0 +1,111 @@ +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: +:: Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +:: Contact: http://www.qt-project.org/legal +:: +:: This file is part of the tools applications of the Qt Toolkit. +:: +:: $QT_BEGIN_LICENSE:LGPL$ +:: Commercial License Usage +:: Licensees holding valid commercial Qt licenses may use this file in +:: accordance with the commercial license agreement provided with the +:: Software or, alternatively, in accordance with the terms contained in +:: a written agreement between you and Digia. For licensing terms and +:: conditions see http://qt.digia.com/licensing. For further information +:: use the contact form at http://qt.digia.com/contact-us. +:: +:: GNU Lesser General Public License Usage +:: Alternatively, this file may be used under the terms of the GNU Lesser +:: General Public License version 2.1 as published by the Free Software +:: Foundation and appearing in the file LICENSE.LGPL included in the +:: packaging of this file. Please review the following information to +:: ensure the GNU Lesser General Public License version 2.1 requirements +:: will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +:: +:: In addition, as a special exception, Digia gives you certain additional +:: rights. These rights are described in the Digia Qt LGPL Exception +:: version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +:: +:: GNU General Public License Usage +:: Alternatively, this file may be used under the terms of the GNU +:: General Public License version 3.0 as published by the Free Software +:: Foundation and appearing in the file LICENSE.GPL included in the +:: packaging of this file. Please review the following information to +:: ensure the GNU General Public License version 3.0 requirements will be +:: met: http://www.gnu.org/copyleft/gpl.html. +:: +:: +:: $QT_END_LICENSE$ +:: +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +@echo off +set QTSRC=%~dp0 +set QTDIR=%CD% +::if not exist %QTSRC%\.gitignore goto sconf +echo Please wait while bootstrapping configure ... + +for %%C in (cl.exe icl.exe g++.exe perl.exe) do set %%C=%%~$PATH:C + +if "%perl.exe%" == "" ( + echo Perl not found in PATH. Aborting. >&2 + exit /b 1 +) +if not exist mkspecs ( + md mkspecs + if errorlevel 1 goto exit +) +perl %QTSRC%bin\syncqt.pl -minimal -module QtCore -outdir %QTDIR% %QTSRC% +if errorlevel 1 goto exit + +if not exist tools\configure ( + md tools\configure + if errorlevel 1 goto exit +) +cd tools\configure +if errorlevel 1 goto exit + +echo #### Generated by configure.bat - DO NOT EDIT! ####> Makefile +echo/>> Makefile +for /f "tokens=3 usebackq" %%V in (`findstr QT_VERSION_STR %QTSRC%\src\corelib\global\qglobal.h`) do @echo QTVERSION = %%~V>> Makefile +if not "%cl.exe%" == "" ( + echo CXX = cl>>Makefile + echo EXTRA_CXXFLAGS =>>Makefile + rem This must have a trailing space. + echo QTSRC = %QTSRC% >> Makefile + set tmpl=win32 + set make=nmake +) else if not "%icl.exe%" == "" ( + echo CXX = icl>>Makefile + echo EXTRA_CXXFLAGS = /Zc:forScope>>Makefile + rem This must have a trailing space. + echo QTSRC = %QTSRC% >> Makefile + set tmpl=win32 + set make=nmake +) else if not "%g++.exe%" == "" ( + echo CXX = g++>>Makefile + echo EXTRA_CXXFLAGS =>>Makefile + rem This must NOT have a trailing space. + echo QTSRC = %QTSRC:\=/%>> Makefile + set tmpl=mingw + set make=mingw32-make +) else ( + echo No suitable compiler found in PATH. Aborting. >&2 + cd ..\.. + exit /b 1 +) +echo/>> Makefile +type %QTSRC%tools\configure\Makefile.%tmpl% >> Makefile + +%make% +if errorlevel 1 (cd ..\.. & exit /b 1) + +cd ..\.. + +:conf +configure.exe -srcdir %QTSRC% %* +goto exit + +:sconf +%QTSRC%\configure.exe %* +:exit diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index 0f2dbbcd4..895b22ae0 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -6,6 +6,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) include_directories(${Boost_INCLUDE_DIRS}) +include_directories(${JSONCPP_INCLUDE_DIRS}) include_directories(..) set(EXECUTABLE solidity) @@ -17,11 +18,9 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -target_link_libraries(${EXECUTABLE} evmcore devcore) -# TODO: Temporary until PR 532 https://github.com/ethereum/cpp-ethereum/pull/532 -# gets accepted. Then we can simply add jsoncpp as a dependency and not the -# whole of JSONRPC as we are doing right here -target_link_libraries(${EXECUTABLE} ${JSONRPC_LS}) +target_link_libraries(${EXECUTABLE} evmcore) +target_link_libraries(${EXECUTABLE} devcore) +target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES}) install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/libsolidity/CompilerStack.h b/libsolidity/CompilerStack.h index 928815cc5..6286eb7ff 100644 --- a/libsolidity/CompilerStack.h +++ b/libsolidity/CompilerStack.h @@ -84,6 +84,22 @@ public: /// scanning the source code - this is useful for printing exception information. static bytes staticCompile(std::string const& _sourceCode, bool _optimize = false); + /// Compile under msvc results in error CC2280 + CompilerStack& operator=(const CompilerStack& _other) + { + m_scanner = _other.m_scanner; + m_globalContext = _other.m_globalContext; + m_contractASTNode = _other.m_contractASTNode; + m_parseSuccessful = _other.m_parseSuccessful; + m_interface.reset(_other.m_interface.get()); + m_userDocumentation.reset(_other.m_userDocumentation.get()); + m_devDocumentation.reset(_other.m_devDocumentation.get()); + m_compiler = _other.m_compiler; + m_interfaceHandler = _other.m_interfaceHandler; + m_bytecode = m_bytecode; + return *this; + } + private: std::shared_ptr m_scanner; std::shared_ptr m_globalContext; diff --git a/libsolidity/InterfaceHandler.h b/libsolidity/InterfaceHandler.h index 524e2903c..a31cd5c11 100644 --- a/libsolidity/InterfaceHandler.h +++ b/libsolidity/InterfaceHandler.h @@ -28,7 +28,7 @@ #include #include -#include +#include namespace dev { diff --git a/lllc/CMakeLists.txt b/lllc/CMakeLists.txt index 0ca19fab9..9549f89e5 100644 --- a/lllc/CMakeLists.txt +++ b/lllc/CMakeLists.txt @@ -3,16 +3,12 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) -include_directories(${Boost_INCLUDE_DIRS}) include_directories(..) set(EXECUTABLE lllc) -if(ETH_STATIC) - add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS}) -else() - add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) -endif() +file(GLOB HEADERS "*.h") +add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) add_dependencies(${EXECUTABLE} BuildInfo.h) diff --git a/solc/CMakeLists.txt b/solc/CMakeLists.txt index ab402ed8e..203a616b4 100644 --- a/solc/CMakeLists.txt +++ b/solc/CMakeLists.txt @@ -3,11 +3,13 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) +include_directories(${Boost_INCLUDE_DIRS}) include_directories(..) set(EXECUTABLE solc) -add_executable(${EXECUTABLE} ${SRC_LIST}) +file(GLOB HEADERS "*.h") +add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) target_link_libraries(${EXECUTABLE} solidity) From 96441cbe9a887065d8af7f3e29367a7e7db8bf3b Mon Sep 17 00:00:00 2001 From: debris Date: Sun, 7 Dec 2014 19:07:51 +0100 Subject: [PATCH 079/277] solc working --- cmake/EthCompilerSettings.cmake | 2 +- cmake/EthDependencies.cmake | 2 +- extdep/compile/boost.cmake | 2 +- libdevcore/CMakeLists.txt | 4 ---- solc/CMakeLists.txt | 4 ++++ 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index 60ea3c90f..69a420333 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -12,7 +12,7 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") - set(CMAKE_CXX_FLAGS "") + set(CMAKE_CXX_FLAGS "/EHsc") set(ETH_STATIC 1) else () message(FATAL_ERROR "Your C++ compiler does not support C++11. You have ${CMAKE_CXX_COMPILER_ID}") diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 223c14ce3..743968dcb 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -51,7 +51,7 @@ set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_MULTITHREADED ON) set(Boost_COMPILER -vc120) -find_package(Boost 1.55.0 REQUIRED COMPONENTS thread date_time system regex) +find_package(Boost 1.55.0 REQUIRED COMPONENTS thread date_time system regex chrono) if (Boost_FOUND) message(" - boost header: ${Boost_INCLUDE_DIRS}") diff --git a/extdep/compile/boost.cmake b/extdep/compile/boost.cmake index aaf892cc9..c87c907b7 100644 --- a/extdep/compile/boost.cmake +++ b/extdep/compile/boost.cmake @@ -5,7 +5,7 @@ set(boost_address_model) # on windows 64: # set(boost_address_model address-model=64) -set(boost_targets --with-filesystem --with-system --with-thread --with-date_time --with-regex --with-test) +set(boost_targets --with-filesystem --with-system --with-thread --with-date_time --with-regex --with-test --with-chrono) ExternalProject_Add(boost URL http://downloads.sourceforge.net/project/boost/boost/1.55.0/boost_1_55_0.tar.gz BINARY_DIR boost-prefix/src/boost diff --git a/libdevcore/CMakeLists.txt b/libdevcore/CMakeLists.txt index 3d103160c..37e6f4c89 100644 --- a/libdevcore/CMakeLists.txt +++ b/libdevcore/CMakeLists.txt @@ -5,7 +5,6 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) -include_directories(${LEVELDB_INCLUDE_DIR}) include_directories(${Boost_INCLUDE_DIRS}) include_directories(..) @@ -19,9 +18,6 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY}) -target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) - if (APPLE) find_package(Threads REQUIRED) target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) diff --git a/solc/CMakeLists.txt b/solc/CMakeLists.txt index 203a616b4..303318502 100644 --- a/solc/CMakeLists.txt +++ b/solc/CMakeLists.txt @@ -11,6 +11,10 @@ set(EXECUTABLE solc) file(GLOB HEADERS "*.h") add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) +target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY_RELEASE}) +target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY_RELEASE}) +target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY_RELEASE}) +target_link_libraries(${EXECUTABLE} ${Boost_CHRONO_LIBRARY_RELEASE}) target_link_libraries(${EXECUTABLE} solidity) install( TARGETS ${EXECUTABLE} DESTINATION bin ) From cd0a5381380c9ae95074a79e5169d6fbd2fb3b6a Mon Sep 17 00:00:00 2001 From: debris Date: Sun, 7 Dec 2014 19:55:40 +0100 Subject: [PATCH 080/277] serpent compiling under msvc --- extdep/CMakeLists.txt | 22 +++++++++++----------- libdevcore/CMakeLists.txt | 5 +++++ libserpent/CMakeLists.txt | 24 ++---------------------- libserpent/rewriter.cpp | 1 + libserpent/util.cpp | 1 + lllc/CMakeLists.txt | 1 + solc/CMakeLists.txt | 4 ---- 7 files changed, 21 insertions(+), 37 deletions(-) diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index f57d6eac8..cea32c80f 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -6,7 +6,7 @@ include(eth_download.cmake) # all dependencies will be installed into this directory, separated by platform string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name) -set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install2/${_system_name}") +set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install/${_system_name}") set(ETH_DEPENDENCY_SERVER "http://poc-7.ethdev.com/precompiled/${_system_name}") file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/lib) file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include) @@ -14,22 +14,22 @@ file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/bin) if (ETH_COMPILE) # json-rpc-cpp and its dependencies - #include(compile/jsoncpp.cmake) - #include(compile/argtable2.cmake) - #include(compile/curl.cmake) - #include(compile/json-rpc-cpp.cmake) + include(compile/jsoncpp.cmake) + include(compile/argtable2.cmake) + include(compile/curl.cmake) + include(compile/json-rpc-cpp.cmake) # qt at its dependencies - #include(compile/icu.cmake) - #include(compile/jom.cmake) - #include(compile/qt.cmake) + include(compile/icu.cmake) + include(compile/jom.cmake) + include(compile/qt.cmake) # leveldb and its dependencies - #include(compile/snappy.cmake) - #include(compile/leveldb.cmake) + include(compile/snappy.cmake) + include(compile/leveldb.cmake) # cryptopp - #include(compile/cryptopp.cmake) + include(compile/cryptopp.cmake) # boost include(compile/boost.cmake) diff --git a/libdevcore/CMakeLists.txt b/libdevcore/CMakeLists.txt index 37e6f4c89..06cbe850c 100644 --- a/libdevcore/CMakeLists.txt +++ b/libdevcore/CMakeLists.txt @@ -18,6 +18,11 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() +target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY_RELEASE}) +target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY_RELEASE}) +target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY_RELEASE}) +target_link_libraries(${EXECUTABLE} ${Boost_CHRONO_LIBRARY_RELEASE}) + if (APPLE) find_package(Threads REQUIRED) target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) diff --git a/libserpent/CMakeLists.txt b/libserpent/CMakeLists.txt index 315970a7a..365b1bc9e 100644 --- a/libserpent/CMakeLists.txt +++ b/libserpent/CMakeLists.txt @@ -5,6 +5,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) +include_directories(..) + set(EXECUTABLE serpent) file(GLOB HEADERS "*.h") @@ -14,32 +16,10 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -include_directories(..) - target_link_libraries(${EXECUTABLE} lll) target_link_libraries(${EXECUTABLE} evmcore) target_link_libraries(${EXECUTABLE} devcore) -if("${TARGET_PLATFORM}" STREQUAL "w64") - target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) - target_link_libraries(${EXECUTABLE} iphlpapi) - target_link_libraries(${EXECUTABLE} ws2_32) - target_link_libraries(${EXECUTABLE} mswsock) - target_link_libraries(${EXECUTABLE} shlwapi) -elseif (APPLE) - # Latest mavericks boost libraries only come with -mt - target_link_libraries(${EXECUTABLE} boost_thread-mt) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -elseif (UNIX) - target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -else () - target_link_libraries(${EXECUTABLE} boost_thread) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -endif () - install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/libserpent/rewriter.cpp b/libserpent/rewriter.cpp index 3042eeb45..443457acf 100644 --- a/libserpent/rewriter.cpp +++ b/libserpent/rewriter.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "util.h" #include "lllparser.h" #include "bignum.h" diff --git a/libserpent/util.cpp b/libserpent/util.cpp index 39eeb20be..fbce5e8b5 100644 --- a/libserpent/util.cpp +++ b/libserpent/util.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "util.h" #include "bignum.h" #include diff --git a/lllc/CMakeLists.txt b/lllc/CMakeLists.txt index 9549f89e5..2e76aa6ff 100644 --- a/lllc/CMakeLists.txt +++ b/lllc/CMakeLists.txt @@ -3,6 +3,7 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) +include_directories(${Boost_INCLUDE_DIRS}) include_directories(..) set(EXECUTABLE lllc) diff --git a/solc/CMakeLists.txt b/solc/CMakeLists.txt index 303318502..203a616b4 100644 --- a/solc/CMakeLists.txt +++ b/solc/CMakeLists.txt @@ -11,10 +11,6 @@ set(EXECUTABLE solc) file(GLOB HEADERS "*.h") add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) -target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY_RELEASE}) -target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY_RELEASE}) -target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY_RELEASE}) -target_link_libraries(${EXECUTABLE} ${Boost_CHRONO_LIBRARY_RELEASE}) target_link_libraries(${EXECUTABLE} solidity) install( TARGETS ${EXECUTABLE} DESTINATION bin ) From 74115e23c580f5cdcca17d8b96686eb9eb94fa3a Mon Sep 17 00:00:00 2001 From: debris Date: Sun, 7 Dec 2014 21:53:25 +0100 Subject: [PATCH 081/277] secp256k1 building under msvc --- secp256k1/CMakeLists.txt | 42 +++++++--------------------------------- 1 file changed, 7 insertions(+), 35 deletions(-) diff --git a/secp256k1/CMakeLists.txt b/secp256k1/CMakeLists.txt index cdfadb265..baa58e7e8 100644 --- a/secp256k1/CMakeLists.txt +++ b/secp256k1/CMakeLists.txt @@ -3,47 +3,19 @@ set(CMAKE_AUTOMOC OFF) set(CMAKE_ASM_COMPILER "yasm") +include_directories(${Boost_INCLUDE_DIRS}) + set(EXECUTABLE secp256k1) file(GLOB HEADERS "*.h") - -if ("${TARGET_PLATFORM}" STREQUAL "w64") - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/field_5x52_asm.o - COMMAND yasm -f win64 -o ${CMAKE_CURRENT_BINARY_DIR}/field_5x52_asm.o ${CMAKE_CURRENT_SOURCE_DIR}/field_5x52_asm.asm - ) - add_custom_target( - asmOut ALL - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/field_5x52_asm.o - ) - if(ETH_STATIC) - add_library(${EXECUTABLE} STATIC ${EXECUTABLE}.c ${CMAKE_CURRENT_BINARY_DIR}/field_5x52_asm.o) - else() - add_library(${EXECUTABLE} SHARED ${EXECUTABLE}.c ${CMAKE_CURRENT_BINARY_DIR}/field_5x52_asm.o) - endif() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -DUSE_FIELD_5X52 -DUSE_FIELD_5X52_ASM -DUSE_NUM_GMP -DUSE_FIELD_INV_NUM") -elseif(APPLE) - if(ETH_STATIC) - add_library(${EXECUTABLE} STATIC ${EXECUTABLE}.c field_5x52_asm.asm) - else() - find_library(GMP_LS gmp /usr/local/lib) - add_library(${EXECUTABLE} SHARED ${EXECUTABLE}.c field_5x52_asm.asm) - endif() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -DUSE_FIELD_GMP -DUSE_NUM_GMP -DUSE_FIELD_INV_NUM") +if(ETH_STATIC) + add_library(${EXECUTABLE} STATIC ${EXECUTABLE}.c) else() - if(ETH_STATIC) - add_library(${EXECUTABLE} STATIC ${EXECUTABLE}.c field_5x52_asm.asm) - else() - add_library(${EXECUTABLE} SHARED ${EXECUTABLE}.c field_5x52_asm.asm) - endif() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -DUSE_FIELD_GMP -DUSE_NUM_GMP -DUSE_FIELD_INV_NUM") + add_library(${EXECUTABLE} SHARED ${EXECUTABLE}.c) endif() -if (NOT GMP_LS) - set(GMP_LS gmp) -endif () - -target_link_libraries(${EXECUTABLE} ${GMP_LS}) +set_target_properties(${EXECUTABLE} PROPERTIES COMPILE_FLAGS "/TP") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUSE_NUM_BOOST -DUSE_FIELD_10X26 -DUSE_FIELD_INV_BUILTIN") install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) From d00c595a74e59cacb155da03aeb58c2ce21cea01 Mon Sep 17 00:00:00 2001 From: debris Date: Sun, 7 Dec 2014 22:13:05 +0100 Subject: [PATCH 082/277] sc and devcrypto working on windows --- cmake/EthDependencies.cmake | 2 +- libdevcrypto/CMakeLists.txt | 18 ++++---------- libp2p/CMakeLists.txt | 47 ++++++------------------------------- sc/CMakeLists.txt | 16 ------------- 4 files changed, 13 insertions(+), 70 deletions(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 743968dcb..fb367ef7b 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -51,7 +51,7 @@ set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_MULTITHREADED ON) set(Boost_COMPILER -vc120) -find_package(Boost 1.55.0 REQUIRED COMPONENTS thread date_time system regex chrono) +find_package(Boost 1.55.0 REQUIRED COMPONENTS thread date_time system regex chrono filesystem) if (Boost_FOUND) message(" - boost header: ${Boost_INCLUDE_DIRS}") diff --git a/libdevcrypto/CMakeLists.txt b/libdevcrypto/CMakeLists.txt index 423a9ccc6..bf564e915 100644 --- a/libdevcrypto/CMakeLists.txt +++ b/libdevcrypto/CMakeLists.txt @@ -3,6 +3,10 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) +include_directories(${CRYPTOPP_INCLUDE_DIR}) +include_directories(${LEVELDB_INCLUDE_DIR}) +include_directories(..) + set(EXECUTABLE devcrypto) file(GLOB HEADERS "*.h") @@ -12,23 +16,11 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -include_directories(${CRYPTOPP_INCLUDE_DIR}) -include_directories(${LEVELDB_INCLUDE_DIR}) -include_directories(..) - +target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY_RELEASE}) target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} secp256k1) -target_link_libraries(${EXECUTABLE} gmp) - -if (APPLE) - # Latest mavericks boost libraries only come with -mt - target_link_libraries(${EXECUTABLE} boost_filesystem-mt) -elseif (UNIX) - find_package(Boost 1.53 REQUIRED COMPONENTS filesystem) - target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY}) -endif () install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/libp2p/CMakeLists.txt b/libp2p/CMakeLists.txt index bae400caf..fa7ff6a54 100644 --- a/libp2p/CMakeLists.txt +++ b/libp2p/CMakeLists.txt @@ -5,6 +5,9 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) +include_directories(..) +include_directories(${LEVELDB_INCLUDE_DIR}) + set(EXECUTABLE p2p) file(GLOB HEADERS "*.h") @@ -14,50 +17,14 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -include_directories(..) -include_directories(${LEVELDB_INCLUDE_DIR}) - -target_link_libraries(${EXECUTABLE} devcrypto) -target_link_libraries(${EXECUTABLE} devcore) -target_link_libraries(${EXECUTABLE} secp256k1) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) -target_link_libraries(${EXECUTABLE} gmp) -if("${TARGET_PLATFORM}" STREQUAL "w64") - target_link_libraries(${EXECUTABLE} boost_system-mt-s) - target_link_libraries(${EXECUTABLE} boost_regex-mt-s) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) - target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) - target_link_libraries(${EXECUTABLE} iphlpapi) - target_link_libraries(${EXECUTABLE} ws2_32) - target_link_libraries(${EXECUTABLE} mswsock) - target_link_libraries(${EXECUTABLE} shlwapi) -elseif (APPLE) - # Latest mavericks boost libraries only come with -mt - target_link_libraries(${EXECUTABLE} boost_system-mt) - target_link_libraries(${EXECUTABLE} boost_regex-mt) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt) - target_link_libraries(${EXECUTABLE} boost_thread-mt) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -elseif (UNIX) - target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -else () - target_link_libraries(${EXECUTABLE} boost_system) - target_link_libraries(${EXECUTABLE} boost_regex) - target_link_libraries(${EXECUTABLE} boost_filesystem) - target_link_libraries(${EXECUTABLE} boost_thread) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -endif () +target_link_libraries(${EXECUTABLE} devcrypto) +target_link_libraries(${EXECUTABLE} devcore) +target_link_libraries(${EXECUTABLE} secp256k1) install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/sc/CMakeLists.txt b/sc/CMakeLists.txt index d977ee967..2adde060e 100644 --- a/sc/CMakeLists.txt +++ b/sc/CMakeLists.txt @@ -13,21 +13,5 @@ target_link_libraries(${EXECUTABLE} lll) target_link_libraries(${EXECUTABLE} evmcore) target_link_libraries(${EXECUTABLE} devcore) -if ("${TARGET_PLATFORM}" STREQUAL "w64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") - target_link_libraries(${EXECUTABLE} gcc) - target_link_libraries(${EXECUTABLE} gdi32) - target_link_libraries(${EXECUTABLE} ws2_32) - target_link_libraries(${EXECUTABLE} mswsock) - target_link_libraries(${EXECUTABLE} shlwapi) - target_link_libraries(${EXECUTABLE} iphlpapi) - target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) - set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) -elseif (UNIX) -else () - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -endif () - install( TARGETS ${EXECUTABLE} DESTINATION bin ) From b4251aac130785f0a9793d8fe2ea409207e12927 Mon Sep 17 00:00:00 2001 From: debris Date: Sun, 7 Dec 2014 22:21:45 +0100 Subject: [PATCH 083/277] evm && ethcore working on windows --- libethcore/CMakeLists.txt | 10 +--------- libevm/CMakeLists.txt | 24 ++++-------------------- 2 files changed, 5 insertions(+), 29 deletions(-) diff --git a/libethcore/CMakeLists.txt b/libethcore/CMakeLists.txt index 99ae26776..869b6092b 100644 --- a/libethcore/CMakeLists.txt +++ b/libethcore/CMakeLists.txt @@ -14,21 +14,13 @@ file(GLOB HEADERS "*.h") if(ETH_STATIC) add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS}) else() - add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) + add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} secp256k1) -target_link_libraries(${EXECUTABLE} gmp) - -if (APPLE) - target_link_libraries(${EXECUTABLE} boost_system-mt) -elseif (UNIX) - find_package(Boost 1.53 REQUIRED COMPONENTS system) - target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY}) -endif() install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/libevm/CMakeLists.txt b/libevm/CMakeLists.txt index 8815d123c..778bce8d9 100644 --- a/libevm/CMakeLists.txt +++ b/libevm/CMakeLists.txt @@ -5,6 +5,9 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) +include_directories(..) +include_directories(${LEVELDB_INCLUDE_DIR}) + set(EXECUTABLE evm) file(GLOB HEADERS "*.h") @@ -14,36 +17,17 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -include_directories(${LEVELDB_INCLUDE_DIR}) -include_directories(..) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) - target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} evmcore) target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} secp256k1) -target_link_libraries(${EXECUTABLE} gmp) - -if (APPLE) - # Latest mavericks boost libraries only come with -mt - target_link_libraries(${EXECUTABLE} boost_system-mt) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt) - target_link_libraries(${EXECUTABLE} boost_thread-mt) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -elseif (UNIX) - target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -endif () install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) From f2a6a21ccab2558f1d35953e969ba28698c77ac2 Mon Sep 17 00:00:00 2001 From: debris Date: Sun, 7 Dec 2014 22:39:01 +0100 Subject: [PATCH 084/277] whisper && webthree working on windows --- libwebthree/CMakeLists.txt | 50 +++++++------------------------------- libwhisper/CMakeLists.txt | 49 ++++++------------------------------- libwhisper/_libwhisper.cpp | 8 ------ 3 files changed, 17 insertions(+), 90 deletions(-) delete mode 100644 libwhisper/_libwhisper.cpp diff --git a/libwebthree/CMakeLists.txt b/libwebthree/CMakeLists.txt index dc623a2fa..2e305a5be 100644 --- a/libwebthree/CMakeLists.txt +++ b/libwebthree/CMakeLists.txt @@ -1,10 +1,13 @@ -cmake_policy(SET CMP0015 NEW) +cmake_policy(SET CMP0015 OLD) set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) +include_directories(${LEVELDB_INCLUDE_DIR}) +include_directories(..) + set(EXECUTABLE webthree) file(GLOB HEADERS "*.h") @@ -14,8 +17,11 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -include_directories(..) -include_directories(${LEVELDB_INCLUDE_DIR}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) + +if(MINIUPNPC_LS) +target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) +endif() target_link_libraries(${EXECUTABLE} ethereum) target_link_libraries(${EXECUTABLE} evm) @@ -25,44 +31,6 @@ target_link_libraries(${EXECUTABLE} p2p) target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} secp256k1) -if(MINIUPNPC_LS) -target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) -endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) -target_link_libraries(${EXECUTABLE} gmp) - -if("${TARGET_PLATFORM}" STREQUAL "w64") - target_link_libraries(${EXECUTABLE} boost_system-mt-s) - target_link_libraries(${EXECUTABLE} boost_regex-mt-s) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) - target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) - target_link_libraries(${EXECUTABLE} iphlpapi) - target_link_libraries(${EXECUTABLE} ws2_32) - target_link_libraries(${EXECUTABLE} mswsock) - target_link_libraries(${EXECUTABLE} shlwapi) -elseif (APPLE) - # Latest mavericks boost libraries only come with -mt - target_link_libraries(${EXECUTABLE} boost_system-mt) - target_link_libraries(${EXECUTABLE} boost_regex-mt) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt) - target_link_libraries(${EXECUTABLE} boost_thread-mt) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -elseif (UNIX) - target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -else () - target_link_libraries(${EXECUTABLE} boost_system) - target_link_libraries(${EXECUTABLE} boost_regex) - target_link_libraries(${EXECUTABLE} boost_filesystem) - target_link_libraries(${EXECUTABLE} boost_thread) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -endif () install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/libwhisper/CMakeLists.txt b/libwhisper/CMakeLists.txt index 080c24c05..51908ffcf 100644 --- a/libwhisper/CMakeLists.txt +++ b/libwhisper/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_policy(SET CMP0015 NEW) +cmake_policy(SET CMP0015 OLD) set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") @@ -17,50 +17,17 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) + +if(MINIUPNPC_LS) +target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) +endif() + target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} p2p) target_link_libraries(${EXECUTABLE} secp256k1) -if(MINIUPNPC_LS) -target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) -endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) -target_link_libraries(${EXECUTABLE} gmp) - -if("${TARGET_PLATFORM}" STREQUAL "w64") - target_link_libraries(${EXECUTABLE} boost_system-mt-s) - target_link_libraries(${EXECUTABLE} boost_regex-mt-s) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) - target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) - target_link_libraries(${EXECUTABLE} iphlpapi) - target_link_libraries(${EXECUTABLE} ws2_32) - target_link_libraries(${EXECUTABLE} mswsock) - target_link_libraries(${EXECUTABLE} shlwapi) -elseif (APPLE) - # Latest mavericks boost libraries only come with -mt - target_link_libraries(${EXECUTABLE} boost_system-mt) - target_link_libraries(${EXECUTABLE} boost_regex-mt) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt) - target_link_libraries(${EXECUTABLE} boost_thread-mt) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -elseif (UNIX) - target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -else () - target_link_libraries(${EXECUTABLE} boost_system) - target_link_libraries(${EXECUTABLE} boost_regex) - target_link_libraries(${EXECUTABLE} boost_filesystem) - target_link_libraries(${EXECUTABLE} boost_thread) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -endif () install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) -install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) - +install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) \ No newline at end of file diff --git a/libwhisper/_libwhisper.cpp b/libwhisper/_libwhisper.cpp deleted file mode 100644 index 813c6a657..000000000 --- a/libwhisper/_libwhisper.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#ifdef _MSC_VER -#include "All.h" -#include "Common.cpp" -#include "WhisperPeer.cpp" -#include "WhisperHost.cpp" -#include "Message.cpp" -#include "Interface.cpp" -#endif From 6f24e77588b9b7252136143a1f28c26ceed6cacf Mon Sep 17 00:00:00 2001 From: debris Date: Mon, 8 Dec 2014 11:17:38 +0100 Subject: [PATCH 085/277] web3jsonrpc, ethereum, qethereum, mix compiling on windows --- eth/CMakeLists.txt | 28 ++++----------------- eth/main.cpp | 3 +-- libethereum/CMakeLists.txt | 18 -------------- libweb3jsonrpc/CMakeLists.txt | 3 +-- libweb3jsonrpc/WebThreeStubServer.cpp | 6 ++--- mix/CMakeLists.txt | 36 ++++----------------------- 6 files changed, 15 insertions(+), 79 deletions(-) diff --git a/eth/CMakeLists.txt b/eth/CMakeLists.txt index 2b88efbc2..575c045d8 100644 --- a/eth/CMakeLists.txt +++ b/eth/CMakeLists.txt @@ -4,7 +4,6 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) -include_directories(${LEVELDB_INCLUDE_DIR}) include_directories(..) set(EXECUTABLE eth) @@ -12,7 +11,11 @@ set(EXECUTABLE eth) file(GLOB HEADERS "*.h") add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) + +add_dependencies(${EXECUTABLE} BuildInfo.h) + +target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARY_RELEASE}) +target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY_RELEASE}) if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) @@ -28,27 +31,6 @@ endif() target_link_libraries(${EXECUTABLE} webthree) target_link_libraries(${EXECUTABLE} secp256k1) -target_link_libraries(${EXECUTABLE} gmp) - -if ("${TARGET_PLATFORM}" STREQUAL "w64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") - target_link_libraries(${EXECUTABLE} boost_system-mt-s) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) - target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) - target_link_libraries(${EXECUTABLE} gcc) - target_link_libraries(${EXECUTABLE} gdi32) - target_link_libraries(${EXECUTABLE} ws2_32) - target_link_libraries(${EXECUTABLE} mswsock) - target_link_libraries(${EXECUTABLE} shlwapi) - target_link_libraries(${EXECUTABLE} iphlpapi) - set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) -elseif (UNIX) -else () - #target_link_libraries(${EXECUTABLE} boost_system) - #target_link_libraries(${EXECUTABLE} boost_filesystem) - #find_package(Threads REQUIRED) - #target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -endif () install( TARGETS ${EXECUTABLE} DESTINATION bin ) diff --git a/eth/main.cpp b/eth/main.cpp index abfc1bfa0..8c370fcef 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -427,8 +427,7 @@ int main(int argc, char** argv) { if (jsonrpc < 0) jsonrpc = 8080; - - jsonrpcConnector = unique_ptr(new jsonrpc::CorsHttpServer(jsonrpc)); + jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc)); jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector({us}))); jsonrpcServer->setIdentities({us}); jsonrpcServer->StartListening(); diff --git a/libethereum/CMakeLists.txt b/libethereum/CMakeLists.txt index ce1b830f5..de750fdb8 100644 --- a/libethereum/CMakeLists.txt +++ b/libethereum/CMakeLists.txt @@ -31,24 +31,6 @@ target_link_libraries(${EXECUTABLE} p2p) target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} secp256k1) -target_link_libraries(${EXECUTABLE} gmp) - -if (APPLE) - # Latest mavericks boost libraries only come with -mt - target_link_libraries(${EXECUTABLE} boost_system-mt) - target_link_libraries(${EXECUTABLE} boost_regex-mt) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt) - target_link_libraries(${EXECUTABLE} boost_thread-mt) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -elseif (UNIX) - target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -endif () install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/libweb3jsonrpc/CMakeLists.txt b/libweb3jsonrpc/CMakeLists.txt index fcc9f0ee9..9925b9026 100644 --- a/libweb3jsonrpc/CMakeLists.txt +++ b/libweb3jsonrpc/CMakeLists.txt @@ -3,9 +3,9 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) +include_directories(..) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) include_directories(${LEVELDB_INCLUDE_DIR}) -include_directories(..) set(EXECUTABLE web3jsonrpc) @@ -28,7 +28,6 @@ endif() target_link_libraries(${EXECUTABLE} webthree) target_link_libraries(${EXECUTABLE} secp256k1) -target_link_libraries(${EXECUTABLE} gmp) target_link_libraries(${EXECUTABLE} solidity) target_link_libraries(${EXECUTABLE} serpent) diff --git a/libweb3jsonrpc/WebThreeStubServer.cpp b/libweb3jsonrpc/WebThreeStubServer.cpp index 1247c5143..c777ab66a 100644 --- a/libweb3jsonrpc/WebThreeStubServer.cpp +++ b/libweb3jsonrpc/WebThreeStubServer.cpp @@ -21,6 +21,9 @@ * @date 2014 */ +#include +#include +#include #include "WebThreeStubServer.h" #include #include @@ -31,9 +34,6 @@ #include #include #include -#include -#include -#include #include using namespace std; diff --git a/mix/CMakeLists.txt b/mix/CMakeLists.txt index 0252b5226..c08e1cbd2 100644 --- a/mix/CMakeLists.txt +++ b/mix/CMakeLists.txt @@ -2,27 +2,6 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) include_directories(..) - -if (APPLE) - # Add homebrew path for qt5 - set(CMAKE_PREFIX_PATH /usr/local/opt/qt5) - include_directories(/usr/local/opt/qt5/include /usr/local/include) -elseif ("${TARGET_PLATFORM}" STREQUAL "w64") - set(SRC_LIST ${SRC_LIST} ../windows/qt_plugin_import.cpp) - include_directories(/usr/x86_64-w64-mingw32/include /usr/x86_64-w64-mingw32/include/QtCore /usr/x86_64-w64-mingw32/include/QtGui /usr/x86_64-w64-mingw32/include/QtQuick /usr/x86_64-w64-mingw32/include/QtQml /usr/x86_64-w64-mingw32/include/QtNetwork /usr/x86_64-w64-mingw32/include/QtWidgets /usr/x86_64-w64-mingw32/include/QtWebKit /usr/x86_64-w64-mingw32/include/QtWebKitWidgets) -elseif (UNIX) - set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ";$ENV{QTDIR}/lib/cmake") -endif () - -find_package(Qt5Core REQUIRED) -find_package(Qt5Gui REQUIRED) -find_package(Qt5Quick REQUIRED) -find_package(Qt5Qml REQUIRED) -find_package(Qt5Network REQUIRED) -find_package(Qt5Widgets REQUIRED) -find_package(Qt5WebKit REQUIRED) -find_package(Qt5WebKitWidgets REQUIRED) - #qt5_wrap_ui(ui_Main.h Main.ui) qt5_add_resources(UI_RESOURCES qml.qrc) @@ -55,8 +34,10 @@ else () add_executable(${EXECUTEABLE} ${SRC_LIST} ${HEADERS} ${UI_RESOURCES}) endif () -qt5_use_modules(${EXECUTEABLE} Core)# Gui Widgets Network WebKit WebKitWidgets) -target_link_libraries(${EXECUTEABLE} webthree qethereum ethereum evm ethcore devcrypto secp256k1 gmp ${CRYPTOPP_LS} serpent lll solidity evmcore devcore web3jsonrpc jsqrc) +#qt5_use_modules(${EXECUTEABLE} Core Gui Widgets Network WebKit WebKitWidgets) +target_link_libraries(${EXECUTEABLE} Qt5::Core) +target_link_libraries(${EXECUTEABLE} Qt5::Gui) +target_link_libraries(${EXECUTEABLE} webthree qethereum ethereum evm ethcore devcrypto secp256k1 ${CRYPTOPP_LS} serpent lll solidity evmcore devcore web3jsonrpc jsqrc) if (APPLE) # First have qt5 install plugins and frameworks @@ -82,13 +63,6 @@ if (APPLE) file(REMOVE \${LINGER_RM}) endif () ") -elseif (UNIX) -else () - target_link_libraries(${EXECUTEABLE} boost_system) - target_link_libraries(${EXECUTEABLE} boost_filesystem) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTEABLE} ${CMAKE_THREAD_LIBS_INIT}) +else() install( TARGETS ${EXECUTEABLE} RUNTIME DESTINATION bin ) endif () - -qt5_use_modules(${EXECUTEABLE} Core Gui) From ad2b462b5db02d5d91e35ca5e3cee5ad3ec027ba Mon Sep 17 00:00:00 2001 From: debris Date: Mon, 8 Dec 2014 12:23:10 +0100 Subject: [PATCH 086/277] common improvements --- alethzero/CMakeLists.txt | 17 ++--------------- cmake/EthDependencies.cmake | 3 ++- libsolidity/Token.h | 3 +++ mix/CMakeLists.txt | 4 ++-- 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index 5b6c5c3c4..a1177a0a3 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_policy(SET CMP0015 NEW) +cmake_policy(SET CMP0015 OLD) set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) @@ -46,7 +46,6 @@ target_link_libraries(${EXECUTABLE} evm) target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} secp256k1) -target_link_libraries(${EXECUTABLE} gmp) target_link_libraries(${EXECUTABLE} serpent) target_link_libraries(${EXECUTABLE} lll) target_link_libraries(${EXECUTABLE} solidity) @@ -80,19 +79,7 @@ if (APPLE) file(REMOVE \${LINGER_RM}) endif () ") -elseif ("${TARGET_PLATFORM}" STREQUAL "w64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-keep-inline-dllexport -static-libgcc -static-libstdc++ -static") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-s -Wl,-subsystem,windows -mthreads -L/usr/x86_64-w64-mingw32/plugins/platforms") - target_link_libraries(${EXECUTABLE} gcc) - target_link_libraries(${EXECUTABLE} mingw32 qtmain mswsock iphlpapi qwindows shlwapi Qt5PlatformSupport opengl32 gdi32 comdlg32 oleaut32 imm32 winmm ole32 uuid ws2_32) - target_link_libraries(${EXECUTABLE} boost_system-mt-s) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) - target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) - target_link_libraries(${EXECUTABLE} crypt32) - target_link_libraries(${EXECUTABLE} Qt5PlatformSupport) - set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) -elseif (UNIX) else () - message(ERROR "platform not supported") + install( TARGETS ${EXECUTEABLE} RUNTIME DESTINATION bin) endif () diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index fb367ef7b..d7542e364 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -4,7 +4,8 @@ # by defining this variable, cmake will look for dependencies first in our own repository before looking in system paths like /usr/local/ ... # this must be set to point to the same directory as $ETH_DEPENDENCY_INSTALL_DIR in /extdep directory string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name) -set (CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install/${_system_name}") +set (CMAKE_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install/${_system_name}") +set (CMAKE_PREFIX_PATH ${CMAKE_DEPENDENCY_INSTALL_DIR}) if (WIN32) set (CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "C:/Program Files/Windows Kits/8.1/Lib/winv6.3/um/x86") #set (CMAKE_PREFIX_PATH "C:/Program Files/Windows Kits/8.1/Lib/winv6.3/um/x64") diff --git a/libsolidity/Token.h b/libsolidity/Token.h index f1a94af35..eb9b4d426 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -296,6 +296,9 @@ class Token { public: // All token values. + // attention! msvc issue: + // http://stackoverflow.com/questions/9567868/compile-errors-after-adding-v8-to-my-project-c2143-c2059 + // @todo: avoid TOKEN_LIST macro #define T(name, string, precedence) name, enum Value { diff --git a/mix/CMakeLists.txt b/mix/CMakeLists.txt index c08e1cbd2..aa1f8cc02 100644 --- a/mix/CMakeLists.txt +++ b/mix/CMakeLists.txt @@ -31,7 +31,7 @@ if (APPLE) else () set(EXECUTEABLE mix) - add_executable(${EXECUTEABLE} ${SRC_LIST} ${HEADERS} ${UI_RESOURCES}) + add_executable(${EXECUTEABLE} ${SRC_LIST} ${HEADERS} ${UI_RESOURCES}) endif () #qt5_use_modules(${EXECUTEABLE} Core Gui Widgets Network WebKit WebKitWidgets) @@ -64,5 +64,5 @@ if (APPLE) endif () ") else() - install( TARGETS ${EXECUTEABLE} RUNTIME DESTINATION bin ) + install( TARGETS ${EXECUTEABLE} RUNTIME DESTINATION bin) endif () From de72fa0edd2ed8a6bbbf283607014244adcc4138 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 8 Dec 2014 13:45:57 +0100 Subject: [PATCH 087/277] - fromRaw, fromString, prettyU256 moved to CommonJS.cpp. - ApplicationCtx => AppContext. - Smart pointer direct method call (instead of calling get() before). - ConstantCompilationModel instanciate as smart pointer. - Bug fix https://github.com/ethereum/cpp-ethereum/issues/557 - Add comments on DebuggingStateWrapper - Coding Standards --- alethzero/MainWin.cpp | 16 ++--- alethzero/MainWin.h | 8 ++- libdevcore/CommonJS.cpp | 70 ++++++++++++++++++++++ libdevcore/CommonJS.h | 7 ++- mix/{ApplicationCtx.cpp => AppContext.cpp} | 32 +++++----- mix/{ApplicationCtx.h => AppContext.h} | 17 +++--- mix/AssemblyDebuggerCtrl.cpp | 15 ++--- mix/AssemblyDebuggerModel.cpp | 8 +-- mix/CodeEditorExtensionManager.cpp | 10 ++-- mix/ConstantCompilationCtrl.cpp | 7 +-- mix/ConstantCompilationCtrl.h | 4 +- mix/ConstantCompilationModel.cpp | 4 +- mix/ConstantCompilationModel.h | 4 +- mix/DebuggingStateWrapper.cpp | 62 ++----------------- mix/DebuggingStateWrapper.h | 23 ++++--- mix/Extension.cpp | 8 +-- mix/TransactionBuilder.cpp | 58 +----------------- mix/TransactionBuilder.h | 36 +++++------ mix/main.cpp | 8 +-- 19 files changed, 183 insertions(+), 214 deletions(-) rename mix/{ApplicationCtx.cpp => AppContext.cpp} (73%) rename mix/{ApplicationCtx.h => AppContext.h} (80%) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 4a32f66b2..0fe55d320 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -64,7 +64,7 @@ static void initUnits(QComboBox* _b) _b->addItem(QString::fromStdString(units()[n].second), n); } -static QString fromRaw(dev::h256 _n, unsigned* _inc = nullptr) +QString Main::fromRaw(dev::h256 _n, unsigned* _inc) { if (_n) { @@ -148,7 +148,7 @@ Main::Main(QWidget *parent) : statusBar()->addPermanentWidget(ui->peerCount); statusBar()->addPermanentWidget(ui->mineStatus); statusBar()->addPermanentWidget(ui->blockCount); - + connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved())); m_webThree.reset(new WebThreeDirect(string("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir() + "/AlethZero", false, {"eth", "shh"})); @@ -173,17 +173,17 @@ Main::Main(QWidget *parent) : connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, this, qweb)); connect(m_qweb, SIGNAL(onNewId(QString)), this, SLOT(addNewId(QString))); }); - + connect(ui->webView, &QWebView::loadFinished, [=]() { m_qweb->poll(); }); - + connect(ui->webView, &QWebView::titleChanged, [=]() { ui->tabWidget->setTabText(0, ui->webView->title()); }); - + readSettings(); installWatches(); startTimer(100); @@ -1067,7 +1067,7 @@ void Main::timerEvent(QTimerEvent*) // 7/18, Alex: aggregating timers, prelude to better threading? // Runs much faster on slower dual-core processors static int interval = 100; - + // refresh mining every 200ms if (interval / 100 % 2 == 0) refreshMining(); @@ -1093,7 +1093,7 @@ void Main::timerEvent(QTimerEvent*) } else interval += 100; - + if (m_qweb) m_qweb->poll(); @@ -1759,7 +1759,7 @@ void Main::on_net_triggered() { ui->port->setEnabled(!ui->net->isChecked()); ui->clientName->setEnabled(!ui->net->isChecked()); - string n = string("AlethZero/v") + dev::Version; + string n = string("AlethZero/v") + dev::Version; if (ui->clientName->text().size()) n += "/" + ui->clientName->text().toStdString(); n += "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM); diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 50b9df413..e4b40dd81 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -69,7 +69,7 @@ struct WorldState class Main : public QMainWindow { Q_OBJECT - + public: explicit Main(QWidget *parent = 0); ~Main(); @@ -79,7 +79,7 @@ public: std::shared_ptr whisper() const { return m_webThree->whisper(); } QList owned() const { return m_myIdentities + m_myKeys; } - + public slots: void load(QString _file); void note(QString _entry); @@ -146,7 +146,7 @@ private slots: void on_debugDumpState_triggered(int _add = 1); void on_debugDumpStatePre_triggered(); void on_refresh_triggered(); - void on_usePrivate_triggered(); + void on_usePrivate_triggered(); void on_enableOptimizer_triggered(); void on_turboMining_triggered(); void on_go_triggered(); @@ -259,4 +259,6 @@ private: QWebThreeConnector* m_qwebConnector; std::unique_ptr m_server; QWebThree* m_qweb = nullptr; + + static QString fromRaw(dev::h256 _n, unsigned* _inc = nullptr); }; diff --git a/libdevcore/CommonJS.cpp b/libdevcore/CommonJS.cpp index c09a5b565..800bd06c8 100644 --- a/libdevcore/CommonJS.cpp +++ b/libdevcore/CommonJS.cpp @@ -54,4 +54,74 @@ bytes unpadded(bytes _b) return _b; } +std::string prettyU256(u256 _n) +{ + unsigned inc = 0; + std::string raw; + std::ostringstream s; + if (!(_n >> 64)) + s << " " << (uint64_t)_n << " (0x" << (uint64_t)_n << ")"; + else if (!~(_n >> 64)) + s << " " << (int64_t)_n << " (0x" << (int64_t)_n << ")"; + else if ((_n >> 160) == 0) + { + Address a = right160(_n); + + std::string n = a.abridged(); + if (n.empty()) + s << "0x" << a; + else + s << n << "(0x" << a.abridged() << ")"; + } + else if ((raw = fromRaw((h256)_n, &inc)).size()) + return "\"" + raw + "\"" + (inc ? " + " + std::to_string(inc) : ""); + else + s << "" << (h256)_n; + return s.str(); +} + +std::string fromRaw(h256 _n, unsigned* _inc) +{ + if (_n) + { + std::string s((char const*)_n.data(), 32); + auto l = s.find_first_of('\0'); + if (!l) + return NULL; + if (l != std::string::npos) + { + auto p = s.find_first_not_of('\0', l); + if (!(p == std::string::npos || (_inc && p == 31))) + return NULL; + if (_inc) + *_inc = (byte)s[31]; + s.resize(l); + } + for (auto i: s) + if (i < 32) + return NULL; + return s; + } + return NULL; +} + +Address fromString(std::string _sn) +{ + if (_sn.size() > 32) + _sn.resize(32); + h256 n; + memcpy(n.data(), _sn.data(), _sn.size()); + memset(n.data() + _sn.size(), 0, 32 - _sn.size()); + if (_sn.size() == 40) + return Address(fromHex(_sn)); + else + return Address(); + //we try to resolve the recipient adress using nameReg contract state + /*const Address c_config = Address("661005d2720d855f1d9976f88bb10c1a3398c77f"); //NameReg contract + if (h160 nameReg = (u160)ethClient->stateAt(c_config, 0)) + if (h256 a = ethClient->stateAt(nameReg, n)) + return right160(a);*/ +} + + } diff --git a/libdevcore/CommonJS.h b/libdevcore/CommonJS.h index 80e1a9ca1..0fb087f72 100644 --- a/libdevcore/CommonJS.h +++ b/libdevcore/CommonJS.h @@ -35,12 +35,12 @@ template std::string toJS(FixedHash const& _h) { return "0x" + toHex(_h.ref()); } - + template std::string toJS(boost::multiprecision::number> const& _n) { return "0x" + toHex(toCompactBigEndian(_n)); } - + inline std::string toJS(dev::bytes const& _n) { return "0x" + dev::toHex(_n); @@ -49,6 +49,9 @@ inline std::string toJS(dev::bytes const& _n) bytes jsToBytes(std::string const& _s); bytes padded(bytes _b, unsigned _l); bytes unpadded(bytes _s); +std::string prettyU256(u256 _n); +std::string fromRaw(h256 _n, unsigned* _inc = nullptr); +Address fromString(std::string _a); template FixedHash jsToFixed(std::string const& _s) { diff --git a/mix/ApplicationCtx.cpp b/mix/AppContext.cpp similarity index 73% rename from mix/ApplicationCtx.cpp rename to mix/AppContext.cpp index 0130f2dfb..5b8b76139 100644 --- a/mix/ApplicationCtx.cpp +++ b/mix/AppContext.cpp @@ -11,12 +11,12 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file ApplicationCtx.cpp +/** @file AppContext.cpp * @author Yann yann@ethdev.com * @date 2014 - * Provides an access to the current QQmlApplicationEngine which is used to add QML file on the fly. + * Provides access to the current QQmlApplicationEngine which is used to add QML file on the fly. * In the future this class can be extended to add more variable related to the context of the application. - * For now ApplicationCtx provides reference to: + * For now AppContext provides reference to: * - QQmlApplicationEngine * - dev::WebThreeDirect (and dev::eth::Client) * - KeyEventManager @@ -28,58 +28,56 @@ #include #include "libdevcrypto/FileSystem.h" #include "KeyEventManager.h" -#include "ApplicationCtx.h" +#include "AppContext.h" using namespace dev; using namespace dev::mix; using namespace dev::eth; -ApplicationCtx* ApplicationCtx::Instance = nullptr; +AppContext* AppContext::Instance = nullptr; -ApplicationCtx::ApplicationCtx(QQmlApplicationEngine* _engine) +AppContext::AppContext(QQmlApplicationEngine* _engine) { m_applicationEngine = std::unique_ptr(_engine); m_keyEventManager = std::unique_ptr(new KeyEventManager()); m_webThree = std::unique_ptr(new WebThreeDirect(std::string("Mix/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir() + "/Mix", false, {"eth", "shh"})); } -QQmlApplicationEngine* ApplicationCtx::appEngine() +QQmlApplicationEngine* AppContext::appEngine() { return m_applicationEngine.get(); } -dev::eth::Client* ApplicationCtx::getEthereumClient() +dev::eth::Client* AppContext::getEthereumClient() { - return m_webThree.get()->ethereum(); + return m_webThree->ethereum(); } -void ApplicationCtx::initKeyEventManager() +void AppContext::initKeyEventManager() { QObject* mainContent = m_applicationEngine->rootObjects().at(0)->findChild("mainContent", Qt::FindChildrenRecursively); if (mainContent) - { QObject::connect(mainContent, SIGNAL(keyPressed(QVariant)), m_keyEventManager.get(), SLOT(keyPressed(QVariant))); - } else qDebug() << "Unable to find QObject of mainContent.qml. KeyEvent will not be handled!"; } -KeyEventManager* ApplicationCtx::getKeyEventManager() +KeyEventManager* AppContext::getKeyEventManager() { return m_keyEventManager.get(); } -void ApplicationCtx::setApplicationContext(QQmlApplicationEngine* _engine) +void AppContext::setApplicationContext(QQmlApplicationEngine* _engine) { if (Instance == nullptr) - Instance = new ApplicationCtx(_engine); + Instance = new AppContext(_engine); } -void ApplicationCtx::displayMessageDialog(QString _title, QString _message) +void AppContext::displayMessageDialog(QString _title, QString _message) { QQmlComponent component(m_applicationEngine.get(), QUrl("qrc:/qml/BasicMessage.qml")); QObject* dialog = component.create(); dialog->findChild("messageContent", Qt::FindChildrenRecursively)->setProperty("text", _message); - QObject* dialogWin = ApplicationCtx::getInstance()->appEngine()->rootObjects().at(0)->findChild("messageDialog", Qt::FindChildrenRecursively); + QObject* dialogWin = AppContext::getInstance()->appEngine()->rootObjects().at(0)->findChild("messageDialog", Qt::FindChildrenRecursively); QMetaObject::invokeMethod(dialogWin, "close"); dialogWin->setProperty("contentItem", QVariant::fromValue(dialog)); dialogWin->setProperty("title", _title); diff --git a/mix/ApplicationCtx.h b/mix/AppContext.h similarity index 80% rename from mix/ApplicationCtx.h rename to mix/AppContext.h index 5680c860e..da7bf9a8d 100644 --- a/mix/ApplicationCtx.h +++ b/mix/AppContext.h @@ -14,11 +14,12 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file ApplicationCtx.h +/** @file AppContext.h * @author Yann yann@ethdev.com - * Provides an access to the current QQmlApplicationEngine which is used to add QML file on the fly. + * @date 2014 + * Provides access to the current QQmlApplicationEngine which is used to add QML file on the fly. * In the future this class can be extended to add more variable related to the context of the application. - * For now ApplicationCtx provides reference to: + * For now AppContext provides reference to: * - QQmlApplicationEngine * - dev::WebThreeDirect (and dev::eth::Client) * - KeyEventManager @@ -36,14 +37,14 @@ namespace dev namespace mix { -class ApplicationCtx: public QObject +class AppContext: public QObject { Q_OBJECT public: - ApplicationCtx(QQmlApplicationEngine* _engine); - ~ApplicationCtx() {} - static ApplicationCtx* getInstance() { return Instance; } + AppContext(QQmlApplicationEngine* _engine); + ~AppContext() {} + static AppContext* getInstance() { return Instance; } static void setApplicationContext(QQmlApplicationEngine* _engine); QQmlApplicationEngine* appEngine(); dev::eth::Client* getEthereumClient(); @@ -52,7 +53,7 @@ public: void displayMessageDialog(QString _title, QString _message); private: - static ApplicationCtx* Instance; + static AppContext* Instance; std::unique_ptr m_applicationEngine; std::unique_ptr m_webThree; std::unique_ptr m_keyEventManager; diff --git a/mix/AssemblyDebuggerCtrl.cpp b/mix/AssemblyDebuggerCtrl.cpp index 94d8bf6cb..6e2b11e70 100644 --- a/mix/AssemblyDebuggerCtrl.cpp +++ b/mix/AssemblyDebuggerCtrl.cpp @@ -25,7 +25,7 @@ #include "AssemblyDebuggerCtrl.h" #include "TransactionBuilder.h" #include "KeyEventManager.h" -#include "ApplicationCtx.h" +#include "AppContext.h" #include "DebuggingStateWrapper.h" using namespace dev::mix; @@ -48,16 +48,17 @@ QString AssemblyDebuggerCtrl::title() const void AssemblyDebuggerCtrl::start() const { //start to listen on F5 - ApplicationCtx::getInstance()->getKeyEventManager()->registerEvent(this, SLOT(keyPressed(int))); + AppContext::getInstance()->getKeyEventManager()->registerEvent(this, SLOT(keyPressed(int))); } void AssemblyDebuggerCtrl::keyPressed(int _key) { + if (_key == Qt::Key_F5) { if (!m_modelDebugger->compile(m_doc->toPlainText())) { - ApplicationCtx::getInstance()->displayMessageDialog("debugger","compilation failed"); + AppContext::getInstance()->displayMessageDialog("debugger","compilation failed"); return; } @@ -71,14 +72,14 @@ void AssemblyDebuggerCtrl::keyPressed(int _key) QList wStates; for(int i = 0; i < debuggingContent.states.size(); i++) { - DebuggingStateWrapper* s = new DebuggingStateWrapper(debuggingContent.executionCode, debuggingContent.executionData.toBytes()); + DebuggingStateWrapper* s = new DebuggingStateWrapper(debuggingContent.executionCode, debuggingContent.executionData.toBytes(), this); s->setState(debuggingContent.states.at(i)); wStates.append(s); } std::tuple, QQMLMap*> code = DebuggingStateWrapper::getHumanReadableCode(debuggingContent.executionCode, this); - ApplicationCtx::getInstance()->appEngine()->rootContext()->setContextProperty("debugStates", QVariant::fromValue(wStates)); - ApplicationCtx::getInstance()->appEngine()->rootContext()->setContextProperty("humanReadableExecutionCode", QVariant::fromValue(std::get<0>(code))); - ApplicationCtx::getInstance()->appEngine()->rootContext()->setContextProperty("bytesCodeMapping", QVariant::fromValue(std::get<1>(code))); + AppContext::getInstance()->appEngine()->rootContext()->setContextProperty("debugStates", QVariant::fromValue(wStates)); + AppContext::getInstance()->appEngine()->rootContext()->setContextProperty("humanReadableExecutionCode", QVariant::fromValue(std::get<0>(code))); + AppContext::getInstance()->appEngine()->rootContext()->setContextProperty("bytesCodeMapping", QVariant::fromValue(std::get<1>(code))); this->addContentOn(this); }; } diff --git a/mix/AssemblyDebuggerModel.cpp b/mix/AssemblyDebuggerModel.cpp index e4c2396ca..aa9795d53 100644 --- a/mix/AssemblyDebuggerModel.cpp +++ b/mix/AssemblyDebuggerModel.cpp @@ -22,7 +22,7 @@ #include "libethereum/ExtVM.h" #include "libevm/VM.h" #include "libdevcore/Common.h" -#include "ApplicationCtx.h" +#include "AppContext.h" #include "TransactionBuilder.h" #include "AssemblyDebuggerModel.h" #include "ConstantCompilationModel.h" @@ -40,7 +40,7 @@ DebuggingContent AssemblyDebuggerModel::getContractInitiationDebugStates(dev::by { QList states; Transaction tr(_rawTransaction); - m_currentExecution.get()->create(tr.sender(), tr.value(), tr.gasPrice(), tr.gas(), &tr.data(), tr.sender()); + m_currentExecution->create(tr.sender(), tr.value(), tr.gasPrice(), tr.gas(), &tr.data(), tr.sender()); std::vector levels; bytes code; bytesConstRef data; @@ -66,8 +66,8 @@ DebuggingContent AssemblyDebuggerModel::getContractInitiationDebugStates(dev::by vm.stack(), vm.memory(), gasCost, ext.state().storage(ext.myAddress), levels})); }; - m_currentExecution.get()->go(onOp); - m_currentExecution.get()->finalize(onOp); + m_currentExecution->go(onOp); + m_currentExecution->finalize(onOp); DebuggingContent d; d.states = states; diff --git a/mix/CodeEditorExtensionManager.cpp b/mix/CodeEditorExtensionManager.cpp index 3bef1a828..78b0f0a7f 100644 --- a/mix/CodeEditorExtensionManager.cpp +++ b/mix/CodeEditorExtensionManager.cpp @@ -28,7 +28,7 @@ #include #include "ConstantCompilationCtrl.h" #include "AssemblyDebuggerCtrl.h" -#include "ApplicationCtx.h" +#include "AppContext.h" #include "CodeEditorExtensionManager.h" using namespace dev::mix; @@ -65,13 +65,13 @@ void CodeEditorExtensionManager::initExtensions() void CodeEditorExtensionManager::initExtension(std::shared_ptr _ext) { - if (!_ext.get()->contentUrl().isEmpty()) + if (!_ext->contentUrl().isEmpty()) { try { - if (_ext.get()->getDisplayBehavior() == ExtensionDisplayBehavior::Tab) + if (_ext->getDisplayBehavior() == ExtensionDisplayBehavior::Tab) { - _ext.get()->addTabOn(m_tabView); + _ext->addTabOn(m_tabView); } } catch (...) @@ -80,7 +80,7 @@ void CodeEditorExtensionManager::initExtension(std::shared_ptr _ext) return; } } - _ext.get()->start(); + _ext->start(); m_features.append(_ext); } diff --git a/mix/ConstantCompilationCtrl.cpp b/mix/ConstantCompilationCtrl.cpp index a703e6686..771387656 100644 --- a/mix/ConstantCompilationCtrl.cpp +++ b/mix/ConstantCompilationCtrl.cpp @@ -33,12 +33,7 @@ using namespace dev::mix; ConstantCompilationCtrl::ConstantCompilationCtrl(QTextDocument* _doc): Extension(ExtensionDisplayBehavior::Tab) { m_editor = _doc; - m_compilationModel = new ConstantCompilationModel(); -} - -ConstantCompilationCtrl::~ConstantCompilationCtrl() -{ - delete m_compilationModel; + m_compilationModel = std::unique_ptr(new ConstantCompilationModel()); } QString ConstantCompilationCtrl::contentUrl() const diff --git a/mix/ConstantCompilationCtrl.h b/mix/ConstantCompilationCtrl.h index e4661c800..446838d39 100644 --- a/mix/ConstantCompilationCtrl.h +++ b/mix/ConstantCompilationCtrl.h @@ -35,14 +35,14 @@ class ConstantCompilationCtrl: public Extension public: ConstantCompilationCtrl(QTextDocument*); - ~ConstantCompilationCtrl(); + ~ConstantCompilationCtrl() {} void start() const override; QString title() const override; QString contentUrl() const override; private: QTextDocument* m_editor; - ConstantCompilationModel* m_compilationModel; + std::unique_ptr m_compilationModel; void writeOutPut(CompilerResult const&); void resetOutPut(); diff --git a/mix/ConstantCompilationModel.cpp b/mix/ConstantCompilationModel.cpp index a6b2f2741..f50ac805b 100644 --- a/mix/ConstantCompilationModel.cpp +++ b/mix/ConstantCompilationModel.cpp @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file ApplicationCtx.h +/** @file ConstantCompilationModel.h * @author Yann yann@ethdev.com * @date 2014 * Ethereum IDE client. @@ -49,7 +49,7 @@ CompilerResult ConstantCompilationModel::compile(QString _code) ostringstream error; solidity::SourceReferenceFormatter::printExceptionInformation(error, _exception, "Error", compiler.getScanner()); res.success = false; - res.comment = QString::fromStdString(error.str()).toHtmlEscaped(); + res.comment = QString::fromStdString(error.str()); res.hexCode = ""; } catch (...) diff --git a/mix/ConstantCompilationModel.h b/mix/ConstantCompilationModel.h index 713c9e950..465cba285 100644 --- a/mix/ConstantCompilationModel.h +++ b/mix/ConstantCompilationModel.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file ApplicationCtx.h +/** @file ConstantCompilationModel.h * @author Yann yann@ethdev.com * @date 2014 * Ethereum IDE client. @@ -45,7 +45,7 @@ class ConstantCompilationModel public: ConstantCompilationModel() {} ~ConstantCompilationModel() {} - CompilerResult compile(QString); + CompilerResult compile(QString _code); }; } diff --git a/mix/DebuggingStateWrapper.cpp b/mix/DebuggingStateWrapper.cpp index d96c975cd..2dde93520 100644 --- a/mix/DebuggingStateWrapper.cpp +++ b/mix/DebuggingStateWrapper.cpp @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file DebuggingState.h +/** @file DebuggingStateWrapper.h * @author Yann yann@ethdev.com * @date 2014 * Used to translate c++ type (u256, bytes, ...) into friendly value (to be used by QML). @@ -23,6 +23,7 @@ #include #include #include +#include "libdevcore/CommonJS.h" #include "libdevcrypto/Common.h" #include "libevmcore/Instruction.h" #include "libdevcore/Common.h" @@ -68,7 +69,7 @@ QString DebuggingStateWrapper::debugStack() { QString stack; for (auto i: m_state.stack) - stack.prepend(prettyU256(i) + "\n"); + stack.prepend(QString::fromStdString(prettyU256(i)) + "\n"); return stack; } @@ -77,7 +78,7 @@ QString DebuggingStateWrapper::debugStorage() { std::stringstream s; for (auto const& i: m_state.storage) - s << "@" << prettyU256(i.first).toStdString() << "    " << prettyU256(i.second).toStdString(); + s << "@" << prettyU256(i.first) << "    " << prettyU256(i.second); return QString::fromStdString(s.str()); } @@ -130,60 +131,9 @@ QString DebuggingStateWrapper::endOfDebug() return "RETURN " + QString::fromStdString(dev::memDump(out, 16, false)); } else if (m_state.inst == Instruction::STOP) - return "STOP"; + return "STOP"; else if (m_state.inst == Instruction::SUICIDE && m_state.stack.size() >= 1) - return "SUICIDE 0x" + QString::fromStdString(toString(right160(m_state.stack.back()))); + return "SUICIDE 0x" + QString::fromStdString(toString(right160(m_state.stack.back()))); else return "EXCEPTION"; } - -QString DebuggingStateWrapper::prettyU256(u256 _n) -{ - unsigned inc = 0; - QString raw; - std::ostringstream s; - if (!(_n >> 64)) - s << " " << (uint64_t)_n << " (0x" << hex << (uint64_t)_n << ")"; - else if (!~(_n >> 64)) - s << " " << (int64_t)_n << " (0x" << hex << (int64_t)_n << ")"; - else if ((_n >> 160) == 0) - { - Address a = right160(_n); - - QString n = QString::fromStdString(a.abridged());//pretty(a); - if (n.isNull()) - s << "0x" << a; - else - s << n.toHtmlEscaped().toStdString() << "(0x" << a.abridged() << ")"; - } - else if ((raw = fromRaw((h256)_n, &inc)).size()) - return "\"" + raw.toHtmlEscaped() + "\"" + (inc ? " + " + QString::number(inc) : ""); - else - s << "" << (h256)_n; - return QString::fromStdString(s.str()); -} - -QString DebuggingStateWrapper::fromRaw(h256 _n, unsigned* _inc) -{ - if (_n) - { - std::string s((char const*)_n.data(), 32); - auto l = s.find_first_of('\0'); - if (!l) - return QString(); - if (l != std::string::npos) - { - auto p = s.find_first_not_of('\0', l); - if (!(p == std::string::npos || (_inc && p == 31))) - return QString(); - if (_inc) - *_inc = (byte)s[31]; - s.resize(l); - } - for (auto i: s) - if (i < 32) - return QString(); - return QString::fromStdString(s); - } - return QString(); -} diff --git a/mix/DebuggingStateWrapper.h b/mix/DebuggingStateWrapper.h index 3f03004b8..df3b8ccce 100644 --- a/mix/DebuggingStateWrapper.h +++ b/mix/DebuggingStateWrapper.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file DebuggingState.h +/** @file DebuggingStateWrapper.h * @author Yann yann@ethdev.com * @date 2014 * Ethereum IDE client. @@ -57,7 +57,9 @@ struct DebuggingContent QString message; }; -/* contains the line nb of the assembly code and the corresponding index in the code bytes array */ +/** + * @brief Contains the line nb of the assembly code and the corresponding index in the code bytes array. + */ class HumanReadableCode: public QObject { Q_OBJECT @@ -74,20 +76,25 @@ private: int m_processIndex; }; -/* used to publish QMap type to QML */ + +/** + * @brief Publish QMap type to QML. + */ class QQMLMap: public QObject { Q_OBJECT public: - QQMLMap(QMap _map, QObject* _parent): QObject(_parent), m_map(_map) { } - Q_INVOKABLE int getValue(int _key) { return m_map.value(_key); } + QQMLMap(QMap _map, QObject* _parent): QObject(_parent), m_map(_map) { } + Q_INVOKABLE int getValue(int _key) { return m_map.value(_key); } private: QMap m_map; }; -/* used to publish DebuggingState struct to QML */ +/** + * @brief Wrap DebuggingState in QObject + */ class DebuggingStateWrapper: public QObject { Q_OBJECT @@ -104,7 +111,7 @@ class DebuggingStateWrapper: public QObject Q_PROPERTY(QStringList levels READ levels) public: - DebuggingStateWrapper(bytes _code, bytes _data) : m_code(_code), m_data(_data) {} + DebuggingStateWrapper(bytes _code, bytes _data, QObject* parent): QObject(parent), m_code(_code), m_data(_data) {} int step() { return (int)m_state.steps; } int curPC() { return (int)m_state.curPC; } int gasCost() { return (int)m_state.gasCost; } @@ -124,8 +131,6 @@ private: DebuggingState m_state; bytes m_code; bytes m_data; - QString prettyU256(u256 _n); - QString fromRaw(h256 _n, unsigned* _inc = nullptr); }; } diff --git a/mix/Extension.cpp b/mix/Extension.cpp index 24cc19aba..410fe85ec 100644 --- a/mix/Extension.cpp +++ b/mix/Extension.cpp @@ -21,7 +21,7 @@ #include #include #include "Extension.h" -#include "ApplicationCtx.h" +#include "AppContext.h" using namespace dev; using namespace dev::mix; @@ -32,7 +32,7 @@ void Extension::addTabOn(QObject* _view) QVariant returnValue; QQmlComponent* component = new QQmlComponent( - ApplicationCtx::getInstance()->appEngine(), + AppContext::getInstance()->appEngine(), QUrl(contentUrl()), _view); QMetaObject::invokeMethod(_view, "addTab", @@ -48,9 +48,9 @@ void Extension::addContentOn(QObject* _view) Q_UNUSED(_view); if (m_displayBehavior == ExtensionDisplayBehavior::ModalDialog) { - QQmlComponent component(ApplicationCtx::getInstance()->appEngine(), QUrl(contentUrl())); + QQmlComponent component(AppContext::getInstance()->appEngine(), QUrl(contentUrl())); QObject* dialog = component.create(); - QObject* dialogWin = ApplicationCtx::getInstance()->appEngine()->rootObjects().at(0)->findChild("dialog", Qt::FindChildrenRecursively); + QObject* dialogWin = AppContext::getInstance()->appEngine()->rootObjects().at(0)->findChild("dialog", Qt::FindChildrenRecursively); QMetaObject::invokeMethod(dialogWin, "close"); dialogWin->setProperty("contentItem", QVariant::fromValue(dialog)); dialogWin->setProperty("title", title()); diff --git a/mix/TransactionBuilder.cpp b/mix/TransactionBuilder.cpp index ce274fa00..bb7cda939 100644 --- a/mix/TransactionBuilder.cpp +++ b/mix/TransactionBuilder.cpp @@ -18,8 +18,9 @@ */ #include "libethereum/Executive.h" +#include "libdevcore/CommonJS.h" #include "libdevcore/Common.h" -#include "ApplicationCtx.h" +#include "AppContext.h" #include "TransactionBuilder.h" using namespace dev::mix; using namespace dev::eth; @@ -34,59 +35,6 @@ Transaction TransactionBuilder::getCreationTransaction(u256 _value, u256 _gasPri Transaction TransactionBuilder::getBasicTransaction(u256 _value, u256 _gasPrice, u256 _gas, QString address, bytes _data, u256 _nonce, Secret _secret) const { - return Transaction(_value, _gasPrice, _gas, fromString(address), _data, _nonce, _secret); + return Transaction(_value, _gasPrice, _gas, dev::fromString(address.toStdString()), _data, _nonce, _secret); } -int TransactionBuilder::fromHex(char _i) const -{ - if (_i >= '0' && _i <= '9') - return _i - '0'; - if (_i >= 'a' && _i <= 'f') - return _i - 'a' + 10; - if (_i >= 'A' && _i <= 'F') - return _i - 'A' + 10; - BOOST_THROW_EXCEPTION(BadHexCharacter() << errinfo_invalidSymbol(_i)); -} - -bytes TransactionBuilder::fromHex(std::string const& _s) const -{ - unsigned s = (_s[0] == '0' && _s[1] == 'x') ? 2 : 0; - std::vector ret; - ret.reserve((_s.size() - s + 1) / 2); - - if (_s.size() % 2) - try - { - ret.push_back(fromHex(_s[s++])); - } - catch (...){ ret.push_back(0); cwarn << boost::current_exception_diagnostic_information(); } - for (unsigned i = s; i < _s.size(); i += 2) - try - { - ret.push_back((byte)(fromHex(_s[i]) * 16 + fromHex(_s[i + 1]))); - } - catch (...){ ret.push_back(0); cwarn << boost::current_exception_diagnostic_information(); } - return ret; -} - -Address TransactionBuilder::fromString(QString const& _a) const -{ - Client* ethClient = ApplicationCtx::getInstance()->getEthereumClient(); - std::string sn = _a.toStdString(); - if (sn.size() > 32) - sn.resize(32); - h256 n; - memcpy(n.data(), sn.data(), sn.size()); - memset(n.data() + sn.size(), 0, 32 - sn.size()); - if (_a.size() == 40) - return Address(fromHex(_a.toStdString())); - else - { - //we try to resolve the recipient adress using nameReg contract state - const Address c_config = Address("661005d2720d855f1d9976f88bb10c1a3398c77f"); //NameReg contract - if (h160 nameReg = (u160)ethClient->stateAt(c_config, 0)) - if (h256 a = ethClient->stateAt(nameReg, n)) - return right160(a); - } - return Address(); // should maybe throws exception instead of returning blank address. -} diff --git a/mix/TransactionBuilder.h b/mix/TransactionBuilder.h index 261d3060f..99f65b024 100644 --- a/mix/TransactionBuilder.h +++ b/mix/TransactionBuilder.h @@ -1,15 +1,15 @@ /* - This file is part of cpp-ethereum. - cpp-ethereum 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. - cpp-ethereum 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 cpp-ethereum. If not, see . + This file is part of cpp-ethereum. + cpp-ethereum 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. + cpp-ethereum 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 cpp-ethereum. If not, see . */ /** @file TransactionBuilder.h * @author Yann yann@ethdev.com @@ -32,15 +32,11 @@ namespace mix class TransactionBuilder { public: - TransactionBuilder() {} - dev::eth::Transaction getBasicTransaction(dev::u256 _value, dev::u256 _gasPrice, dev::u256 _gas, - QString address, bytes _data, dev::u256 _nonce, Secret _secret) const; - dev::eth::Transaction getCreationTransaction(dev::u256 _value, dev::u256 _gasPrice, dev::u256 _gas, - dev::bytes _data, dev::u256 _nonce, Secret _secret) const; -private: - bytes fromHex(std::string const& _s) const; - int fromHex(char _i) const; - Address fromString(QString const& _a) const; + TransactionBuilder() {} + dev::eth::Transaction getBasicTransaction(dev::u256 _value, dev::u256 _gasPrice, dev::u256 _gas, + QString address, bytes _data, dev::u256 _nonce, Secret _secret) const; + dev::eth::Transaction getCreationTransaction(dev::u256 _value, dev::u256 _gasPrice, dev::u256 _gas, + dev::bytes _data, dev::u256 _nonce, Secret _secret) const; }; } diff --git a/mix/main.cpp b/mix/main.cpp index 4f707f47a..33a139f85 100644 --- a/mix/main.cpp +++ b/mix/main.cpp @@ -24,7 +24,7 @@ #include #include #include "CodeEditorExtensionManager.h" -#include "ApplicationCtx.h" +#include "AppContext.h" #include "MixApplication.h" using namespace dev::mix; @@ -33,11 +33,11 @@ int main(int _argc, char *_argv[]) QApplication app(_argc, _argv); qmlRegisterType("CodeEditorExtensionManager", 1, 0, "CodeEditorExtensionManager"); QQmlApplicationEngine* engine = new QQmlApplicationEngine(); - ApplicationCtx::setApplicationContext(engine); - QObject::connect(&app, SIGNAL(lastWindowClosed()), ApplicationCtx::getInstance(), SLOT(quitApplication())); //use to kill ApplicationContext and other stuff + AppContext::setApplicationContext(engine); + QObject::connect(&app, SIGNAL(lastWindowClosed()), AppContext::getInstance(), SLOT(quitApplication())); //use to kill ApplicationContext and other stuff engine->load(QUrl(QStringLiteral("qrc:/qml/main.qml"))); - ApplicationCtx::getInstance()->initKeyEventManager(); //has to be called after the loading of the main view. + AppContext::getInstance()->initKeyEventManager(); //has to be called after the loading of the main view. return app.exec(); } From f7c44f38661a16dde03e5831a5ecc192bfefbf6a Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Mon, 8 Dec 2014 13:55:54 +0100 Subject: [PATCH 088/277] project working on mac, FindGmp.cmake && couple of todos --- cmake/EthDependencies.cmake | 29 +++++++++++++++++++++-------- cmake/FindGmp.cmake | 32 ++++++++++++++++++++++++++++++++ cmake/FindLevelDB.cmake | 2 +- libethereum/CMakeLists.txt | 7 ++++--- secp256k1/CMakeLists.txt | 33 +++++++++++++++++++++++---------- 5 files changed, 81 insertions(+), 22 deletions(-) create mode 100644 cmake/FindGmp.cmake diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index d7542e364..7b756c3d5 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -6,7 +6,12 @@ string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name) set (CMAKE_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install/${_system_name}") set (CMAKE_PREFIX_PATH ${CMAKE_DEPENDENCY_INSTALL_DIR}) -if (WIN32) + +# Qt5 requires opengl +# TODO use proper version of windows SDK (32 vs 64) +# TODO make it possible to use older versions of windows SDK (7.0+ should also work) +# TODO it windows SDK is NOT FOUND, throw ERROR +if (${CMAKE_CXX_COMPILER_ID} MATCHES "MSVC") set (CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "C:/Program Files/Windows Kits/8.1/Lib/winv6.3/um/x86") #set (CMAKE_PREFIX_PATH "C:/Program Files/Windows Kits/8.1/Lib/winv6.3/um/x64") endif() @@ -28,6 +33,7 @@ message(" - Jsoncpp lib : ${JSONCPP_LIBRARIES}") # TODO the JsonRpcCpp package does not yet check for correct version number # json-rpc-cpp support is currently not mandatory +# TODO make headless client optional find_package (JsonRpcCpp 0.3.2) if (${JSON_RPC_CPP_FOUND}) message (" - json-rpc-cpp header: ${JSON_RPC_CPP_INCLUDE_DIRS}") @@ -35,6 +41,13 @@ if (${JSON_RPC_CPP_FOUND}) add_definitions(-DETH_JSONRPC) endif() +# TODO gmp package does not yet check for correct version number +# TODO it is also not required in msvc build +find_package (Gmp 6.0.0) +message(" - Gmp Header: ${GMP_INCLUDE_DIR}") +message(" - Gmp lib : ${GMP_LIBRARY}") + +# TODO make headless client optional find_package (QT5Core REQUIRED) find_package (QT5Gui REQUIRED) find_package (Qt5Quick REQUIRED) @@ -46,18 +59,18 @@ find_package (Qt5WebKitWidgets REQUIRED) # we have to specify here if we want static and boost version, that is really important - -# win32 msvc 2013 boost set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_MULTITHREADED ON) -set(Boost_COMPILER -vc120) + +# TODO hanlde other msvc versions or it will fail find them +if (${CMAKE_CXX_COMPILER_ID} MATCHES "MSVC") + set(Boost_COMPILER -vc120) +endif() find_package(Boost 1.55.0 REQUIRED COMPONENTS thread date_time system regex chrono filesystem) -if (Boost_FOUND) - message(" - boost header: ${Boost_INCLUDE_DIRS}") - message(" - boost lib : ${Boost_LIBRARIES}") -endif() +message(" - boost header: ${Boost_INCLUDE_DIRS}") +message(" - boost lib : ${Boost_LIBRARIES}") diff --git a/cmake/FindGmp.cmake b/cmake/FindGmp.cmake new file mode 100644 index 000000000..908499865 --- /dev/null +++ b/cmake/FindGmp.cmake @@ -0,0 +1,32 @@ +# Find gmp +# +# Find the gmp includes and library +# +# if you nee to add a custom library search path, do it via via CMAKE_FIND_ROOT_PATH +# +# This module defines +# GMP_INCLUDE_DIR, where to find header, etc. +# GMP_LIBRARY, the libraries needed to use leveldb. +# GMP_FOUND, If false, do not try to use leveldb. + +# only look in default directories +find_path( + GMP_INCLUDE_DIR + NAMES gmp.h + DOC "gmp include dir" + ) + +find_library( + GMP_LIBRARY + NAMES gmp + DOC "gmp library" + ) + + +# handle the QUIETLY and REQUIRED arguments and set GMP_FOUND to TRUE +# if all listed variables are TRUE, hide their existence from configuration view +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(gmp DEFAULT_MSG + GMP_INCLUDE_DIR GMP_LIBRARY) +mark_as_advanced (GMP_INCLUDE_DIR GMP_LIBRARY) + diff --git a/cmake/FindLevelDB.cmake b/cmake/FindLevelDB.cmake index 770c9e65f..26629d35f 100644 --- a/cmake/FindLevelDB.cmake +++ b/cmake/FindLevelDB.cmake @@ -26,7 +26,7 @@ find_library( # message (" - leveldb lib : ${LEVELDB_LIBRARY}") -# handle the QUIETLY and REQUIRED arguments and set JSON_RPC_CPP_FOUND to TRUE +# handle the QUIETLY and REQUIRED arguments and set LEVELDB_FOUND to TRUE # if all listed variables are TRUE, hide their existence from configuration view include(FindPackageHandleStandardArgs) find_package_handle_standard_args(leveldb DEFAULT_MSG diff --git a/libethereum/CMakeLists.txt b/libethereum/CMakeLists.txt index de750fdb8..e9904e9a8 100644 --- a/libethereum/CMakeLists.txt +++ b/libethereum/CMakeLists.txt @@ -5,6 +5,9 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) +include_directories(${LEVELDB_INCLUDE_DIR}) +include_directories(..) + set(EXECUTABLE ethereum) file(GLOB HEADERS "*.h") @@ -15,10 +18,8 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -include_directories(${LEVELDB_INCLUDE_DIR}) -include_directories(..) - target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARY_RELEASE}) if (MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) diff --git a/secp256k1/CMakeLists.txt b/secp256k1/CMakeLists.txt index baa58e7e8..f02bba238 100644 --- a/secp256k1/CMakeLists.txt +++ b/secp256k1/CMakeLists.txt @@ -3,19 +3,32 @@ set(CMAKE_AUTOMOC OFF) set(CMAKE_ASM_COMPILER "yasm") -include_directories(${Boost_INCLUDE_DIRS}) - set(EXECUTABLE secp256k1) - file(GLOB HEADERS "*.h") -if(ETH_STATIC) - add_library(${EXECUTABLE} STATIC ${EXECUTABLE}.c) -else() - add_library(${EXECUTABLE} SHARED ${EXECUTABLE}.c) -endif() -set_target_properties(${EXECUTABLE} PROPERTIES COMPILE_FLAGS "/TP") -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUSE_NUM_BOOST -DUSE_FIELD_10X26 -DUSE_FIELD_INV_BUILTIN") +if (${CMAKE_CXX_COMPILER_ID} MATCHES "MSVC") + + include_directories(${Boost_INCLUDE_DIRS}) + if(ETH_STATIC) + add_library(${EXECUTABLE} STATIC ${EXECUTABLE}.c) + else() + add_library(${EXECUTABLE} SHARED ${EXECUTABLE}.c) + endif() + # /TP - compile project as cpp project + set_target_properties(${EXECUTABLE} PROPERTIES COMPILE_FLAGS "/TP") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUSE_NUM_BOOST -DUSE_FIELD_10X26 -DUSE_FIELD_INV_BUILTIN") + +elseif (APPLE OR UNIX) + + if (ETH_STATIC) + add_library(${EXECUTABLE} STATIC ${EXECUTABLE}.c field_5x52_asm.asm) + else() + add_library(${EXECUTABLE} SHARED ${EXECUTABLE}.c field_5x52_asm.asm) + endif() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -DUSE_FIELD_GMP -DUSE_NUM_GMP -DUSE_FIELD_INV_NUM") + target_link_libraries(${EXECUTABLE} ${GMP_LIBRARY}) + +endif() install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) From d5b343994a5f86aee9cad7556f4a15877d0d2f8b Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Mon, 8 Dec 2014 14:12:28 +0100 Subject: [PATCH 089/277] removed few unused lines from cmakes --- cmake/EthCompilerSettings.cmake | 51 ++++++++------------------------- libsolidity/CompilerStack.h | 16 ----------- 2 files changed, 12 insertions(+), 55 deletions(-) diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index 69a420333..ba24b62e2 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -1,25 +1,32 @@ # Set necessary compile and link flags - # C++11 check and activation if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") - set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB") + + set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB -fPIC") + set(ETH_SHARED 1) execute_process( COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) if (NOT (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7)) message(FATAL_ERROR "${PROJECT_NAME} requires g++ 4.7 or greater.") endif () + elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB") + + set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB -fPIC") + set(ETH_SHARED 1) + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + + # specify Exception Handling Model in msvc set(CMAKE_CXX_FLAGS "/EHsc") + # windows likes static set(ETH_STATIC 1) + else () message(FATAL_ERROR "Your C++ compiler does not support C++11. You have ${CMAKE_CXX_COMPILER_ID}") endif () - - # Initialize CXXFLAGS # CMAKE_CXX_FLAGS was set before set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DETH_DEBUG") @@ -27,37 +34,3 @@ set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE") set(CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG -DETH_RELEASE") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_DEBUG") -# Windows -#if ("${TARGET_PLATFORM}" STREQUAL "w64") -# set(CMAKE_SYSTEM_NAME Windows) -# -# set(CMAKE_CXX_LIBRARY_ARCHITECTURE x86_64-w64-mingw32) -# set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) -# set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) -# set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) -# set(CMAKE_AR x86_64-w64-mingw32-ar) -# set(CMAKE_RANLIB x86_64-w64-mingw32-ranlib) -# -# set(CMAKE_EXECUTABLE_SUFFIX .exe) -# -# set(CMAKE_FIND_ROOT_PATH -# /usr/x86_64-w64-mingw32 -# ) -# -# include_directories(/usr/x86_64-w64-mingw32/include/cryptopp) -# -# set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -# set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -# set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -# -# set(CMAKE_INSTALL_PREFIX /usr/x86_64-w64-mingw32) -# set(ETH_BUILD_PLATFORM "windows") -# set(ETH_STATIC 1) -#else () -# set(ETH_BUILD_PLATFORM ${CMAKE_SYSTEM_NAME}) -# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") -# set(ETH_SHARED 1) -#endif() - - - diff --git a/libsolidity/CompilerStack.h b/libsolidity/CompilerStack.h index 6f036d3f3..82d275498 100644 --- a/libsolidity/CompilerStack.h +++ b/libsolidity/CompilerStack.h @@ -94,22 +94,6 @@ public: /// scanning the source code - this is useful for printing exception information. static bytes staticCompile(std::string const& _sourceCode, bool _optimize = false); - /// Compile under msvc results in error CC2280 - CompilerStack& operator=(const CompilerStack& _other) - { - m_scanner = _other.m_scanner; - m_globalContext = _other.m_globalContext; - m_contractASTNode = _other.m_contractASTNode; - m_parseSuccessful = _other.m_parseSuccessful; - m_interface.reset(_other.m_interface.get()); - m_userDocumentation.reset(_other.m_userDocumentation.get()); - m_devDocumentation.reset(_other.m_devDocumentation.get()); - m_compiler = _other.m_compiler; - m_interfaceHandler = _other.m_interfaceHandler; - m_bytecode = m_bytecode; - return *this; - } - private: /** * Information pertaining to one source unit, filled gradually during parsing and compilation. From 5a874b4abb001afde8ad70f78aa638213b0ed0e5 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Mon, 8 Dec 2014 14:48:42 +0100 Subject: [PATCH 090/277] removed EthDependenciesDeprecated --- CMakeLists.txt | 4 - cmake/EthDependencies.cmake | 47 ++++++----- cmake/EthDependenciesDeprecated.cmake | 110 -------------------------- cmake/FindGmp.cmake | 5 +- cmake/FindMiniupnpc.cmake | 31 ++++++++ cmake/FindReadline.cmake | 31 ++++++++ eth/CMakeLists.txt | 8 +- exp/CMakeLists.txt | 4 +- libethereum/CMakeLists.txt | 4 +- libevm/CMakeLists.txt | 4 +- libp2p/CMakeLists.txt | 4 +- libweb3jsonrpc/CMakeLists.txt | 4 +- libwebthree/CMakeLists.txt | 4 +- libwhisper/CMakeLists.txt | 4 +- neth/CMakeLists.txt | 4 +- 15 files changed, 112 insertions(+), 156 deletions(-) delete mode 100644 cmake/EthDependenciesDeprecated.cmake create mode 100644 cmake/FindMiniupnpc.cmake create mode 100644 cmake/FindReadline.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index d4be26923..d070ccc1e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,10 +105,6 @@ message("-- CXXFLAGS: ${CMAKE_CXX_FLAGS}") # this must be an include, as a function it would messs up with variable scope! include(EthDependencies) - -# TODO this will go away soon! -include(EthDependenciesDeprecated) - createBuildInfo() add_subdirectory(libdevcore) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 7b756c3d5..77cd3bfe7 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -34,18 +34,39 @@ message(" - Jsoncpp lib : ${JSONCPP_LIBRARIES}") # TODO the JsonRpcCpp package does not yet check for correct version number # json-rpc-cpp support is currently not mandatory # TODO make headless client optional +# TODO get rid of -DETH_JSONRPC find_package (JsonRpcCpp 0.3.2) -if (${JSON_RPC_CPP_FOUND}) +if (JSON_RPC_CPP_FOUND) message (" - json-rpc-cpp header: ${JSON_RPC_CPP_INCLUDE_DIRS}") message (" - json-rpc-cpp lib : ${JSON_RPC_CPP_LIBRARIES}") add_definitions(-DETH_JSONRPC) endif() +# TODO readline package does not yet check for correct version number +# TODO make readline package dependent on cmake options +# TODO get rid of -DETH_READLINE +find_package (Readline 6.3.8) +if (READLINE_FOUND) + message (" - readline header: ${READLINE_INCLUDE_DIR}") + message (" - readline lib : ${READLINE_LIBRARY}") + add_definitions(-DETH_READLINE) +endif () + +# TODO miniupnpc package does not yet check for correct version number +# TODO make miniupnpc package dependent on cmake options +# TODO get rid of -DMINIUPNPC +find_package (Miniupnpc 1.8.2013) +if (MINIUPNPC_FOUND) + message (" - miniupnpc header: ${MINIUPNPC_INCLUDE_DIR}") + message (" - miniupnpc lib : ${MINIUPNPC_LIBRARY}") + add_definitions(-DETH_MINIUPNPC) +endif() + # TODO gmp package does not yet check for correct version number # TODO it is also not required in msvc build find_package (Gmp 6.0.0) -message(" - Gmp Header: ${GMP_INCLUDE_DIR}") -message(" - Gmp lib : ${GMP_LIBRARY}") +message(" - gmp Header: ${GMP_INCLUDE_DIR}") +message(" - gmp lib : ${GMP_LIBRARY}") # TODO make headless client optional find_package (QT5Core REQUIRED) @@ -57,7 +78,6 @@ find_package (Qt5Widgets REQUIRED) find_package (Qt5WebKit REQUIRED) find_package (Qt5WebKitWidgets REQUIRED) - # we have to specify here if we want static and boost version, that is really important set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_MULTITHREADED ON) @@ -72,19 +92,8 @@ find_package(Boost 1.55.0 REQUIRED COMPONENTS thread date_time system regex chro message(" - boost header: ${Boost_INCLUDE_DIRS}") message(" - boost lib : ${Boost_LIBRARIES}") - - - - - - - - - - - - - - - +if (APPLE) + link_directories(/usr/local/lib) + include_directories(/usr/local/include) +endif() diff --git a/cmake/EthDependenciesDeprecated.cmake b/cmake/EthDependenciesDeprecated.cmake deleted file mode 100644 index 72ad9c769..000000000 --- a/cmake/EthDependenciesDeprecated.cmake +++ /dev/null @@ -1,110 +0,0 @@ -# search for and configure dependencies - -# deprecated. DO NOT ADD any new stuff here. Proper dependency fetching is done in EthDependencies.cmake - - -if("${TARGET_PLATFORM}" STREQUAL "w64") -# set(MINIUPNPC_LS /usr/x86_64-w64-mingw32/lib/libminiupnpc.a) -else() - - find_path( PYTHON_ID pyconfig.h - ${PYTHON_INCLUDE_DIR} - /usr/include/python2.7 - /usr/local/include/python2.7 - ) - if ( PYTHON_ID STREQUAL "PYTHON_ID-NOTFOUND" ) - message(STATUS "Failed to find the Python-2.7 headers") - else () - message(STATUS "Found Python-2.7 Headers: ${PYTHON_ID}") - - # Check for accessory dev libraries leveldb and miniupnpc - find_library( PYTHON_LS NAMES python2.7 - PATHS - /usr/lib - /usr/local/lib - /opt/local/lib - /usr/lib/*/ - ) - if ( PYTHON_LS STREQUAL "PYTHON_LS-NOTFOUND" ) - message(STATUS "Failed to find the Python-2.7 Library!") - set(PYTHON_ID) - set(PYTHON_LS) - else () - message(STATUS "Found Python-2.7 Library: ${PYTHON_LS}") - add_definitions(-DETH_PYTHON) - endif () - endif () - - find_path( MINIUPNPC_ID miniupnpc/miniwget.h - /usr/include - /usr/local/include - ) - if ( MINIUPNPC_ID ) - message(STATUS "Found miniupnpc headers") - - find_library( MINIUPNPC_LS NAMES miniupnpc - PATHS - /usr/lib - /usr/local/lib - /opt/local/lib - /usr/lib/*/ - ) - if ( MINIUPNPC_LS ) - message(STATUS "Found miniupnpc library: ${MINIUPNPC_LS}") - add_definitions(-DETH_MINIUPNPC) - else () - message(STATUS "Failed to find the miniupnpc library!") - endif () - else () - message(STATUS "Failed to find the miniupnpc headers!") - endif () - - find_path( READLINE_ID readline/readline.h - /usr/include - /usr/local/include - ) - if ( READLINE_ID ) - message(STATUS "Found readline headers") - find_library( READLINE_LS NAMES readline - PATHS - /usr/lib - /usr/local/lib - /opt/local/lib - /usr/lib/*/ - ) - if ( READLINE_LS ) - message(STATUS "Found readline library: ${READLINE_LS}") - add_definitions(-DETH_READLINE) - else () - message(STATUS "Failed to find the readline library!") - endif () - else () - message(STATUS "Failed to find the readline headers!") - endif () - - #if (LANGUAGES) - # find_package(Boost 1.53 REQUIRED COMPONENTS thread date_time) - #else() - # find_package(Boost 1.53 REQUIRED COMPONENTS thread date_time system regex) - #endif() - - set(QTQML 1) -endif() - -if(PYTHON_ID) - include_directories(${PYTHON_ID}) -endif() -if(MINIUPNPC_ID) - include_directories(${MINIUPNPC_ID}) -endif() -if(READLINE_ID) - include_directories(${READLINE_ID}) -endif() - - - - -if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - link_directories(/usr/local/lib) - include_directories(/usr/local/include) -endif() diff --git a/cmake/FindGmp.cmake b/cmake/FindGmp.cmake index 908499865..4d7a3a04c 100644 --- a/cmake/FindGmp.cmake +++ b/cmake/FindGmp.cmake @@ -6,8 +6,8 @@ # # This module defines # GMP_INCLUDE_DIR, where to find header, etc. -# GMP_LIBRARY, the libraries needed to use leveldb. -# GMP_FOUND, If false, do not try to use leveldb. +# GMP_LIBRARY, the libraries needed to use gmp. +# GMP_FOUND, If false, do not try to use gmp. # only look in default directories find_path( @@ -22,7 +22,6 @@ find_library( DOC "gmp library" ) - # handle the QUIETLY and REQUIRED arguments and set GMP_FOUND to TRUE # if all listed variables are TRUE, hide their existence from configuration view include(FindPackageHandleStandardArgs) diff --git a/cmake/FindMiniupnpc.cmake b/cmake/FindMiniupnpc.cmake new file mode 100644 index 000000000..90a202dce --- /dev/null +++ b/cmake/FindMiniupnpc.cmake @@ -0,0 +1,31 @@ +# Find miniupnpc +# +# Find the miniupnpc includes and library +# +# if you nee to add a custom library search path, do it via via CMAKE_FIND_ROOT_PATH +# +# This module defines +# MINIUPNPC_INCLUDE_DIR, where to find header, etc. +# MINIUPNPC_LIBRARY, the libraries needed to use gmp. +# MINIUPNPC_FOUND, If false, do not try to use gmp. + +# only look in default directories +find_path( + MINIUPNPC_INCLUDE_DIR + NAMES miniupnpc/miniupnpc.h + DOC "miniupnpc include dir" + ) + +find_library( + MINIUPNPC_LIBRARY + NAMES miniupnpc + DOC "miniupnpc library" + ) + +# handle the QUIETLY and REQUIRED arguments and set MINIUPNPC_FOUND to TRUE +# if all listed variables are TRUE, hide their existence from configuration view +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(miniupnpc DEFAULT_MSG + MINIUPNPC_INCLUDE_DIR MINIUPNPC_LIBRARY) +mark_as_advanced (MINIUPNPC_INCLUDE_DIR MINIUPNPC_LIBRARY) + diff --git a/cmake/FindReadline.cmake b/cmake/FindReadline.cmake new file mode 100644 index 000000000..16eb483ee --- /dev/null +++ b/cmake/FindReadline.cmake @@ -0,0 +1,31 @@ +# Find readline +# +# Find the readline includes and library +# +# if you nee to add a custom library search path, do it via via CMAKE_FIND_ROOT_PATH +# +# This module defines +# READLINE_INCLUDE_DIR, where to find header, etc. +# READLINE_LIBRARY, the libraries needed to use readline. +# READLINE_FOUND, If false, do not try to use readline. + +# only look in default directories +find_path( + READLINE_INCLUDE_DIR + NAMES readline/readline.h + DOC "readling include dir" + ) + +find_library( + READLINE_LIBRARY + NAMES readline + DOC "readline library" + ) + +# handle the QUIETLY and REQUIRED arguments and set READLINE_FOUND to TRUE +# if all listed variables are TRUE, hide their existence from configuration view +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(readline DEFAULT_MSG + READLINE_INCLUDE_DIR READLINE_LIBRARY) +mark_as_advanced (READLINE_INCLUDE_DIR READLINE_LIBRARY) + diff --git a/eth/CMakeLists.txt b/eth/CMakeLists.txt index 575c045d8..fe5571f60 100644 --- a/eth/CMakeLists.txt +++ b/eth/CMakeLists.txt @@ -17,16 +17,16 @@ add_dependencies(${EXECUTABLE} BuildInfo.h) target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARY_RELEASE}) target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY_RELEASE}) -if(MINIUPNPC_LS) - target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) +if(MINIUPNPC_FOUND) + target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) endif() if(JSON_RPC_CPP_FOUND) target_link_libraries(${EXECUTABLE} web3jsonrpc) endif() -if(READLINE_LS) -target_link_libraries(${EXECUTABLE} ${READLINE_LS}) +if (READLINE_FOUND) +target_link_libraries(${EXECUTABLE} ${READLINE_LIBRARY}) endif() target_link_libraries(${EXECUTABLE} webthree) diff --git a/exp/CMakeLists.txt b/exp/CMakeLists.txt index 6fcea5341..1cd5218e2 100644 --- a/exp/CMakeLists.txt +++ b/exp/CMakeLists.txt @@ -12,8 +12,8 @@ add_executable(${EXECUTABLE} ${SRC_LIST}) target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) -if(MINIUPNPC_LS) -target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) +if(MINIUPNPC_FOUND) +target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) endif() target_link_libraries(${EXECUTABLE} ethereum) diff --git a/libethereum/CMakeLists.txt b/libethereum/CMakeLists.txt index e9904e9a8..ac5bd7136 100644 --- a/libethereum/CMakeLists.txt +++ b/libethereum/CMakeLists.txt @@ -21,8 +21,8 @@ endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARY_RELEASE}) -if (MINIUPNPC_LS) -target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) +if (MINIUPNPC_FOUND) +target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) endif() target_link_libraries(${EXECUTABLE} evm) diff --git a/libevm/CMakeLists.txt b/libevm/CMakeLists.txt index 778bce8d9..717904912 100644 --- a/libevm/CMakeLists.txt +++ b/libevm/CMakeLists.txt @@ -19,8 +19,8 @@ endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) -if(MINIUPNPC_LS) -target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) +if(MINIUPNPC_FOUND) +target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) endif() target_link_libraries(${EXECUTABLE} ethcore) diff --git a/libp2p/CMakeLists.txt b/libp2p/CMakeLists.txt index fa7ff6a54..e354a1c65 100644 --- a/libp2p/CMakeLists.txt +++ b/libp2p/CMakeLists.txt @@ -18,8 +18,8 @@ else() endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) -if(MINIUPNPC_LS) -target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) +if(MINIUPNPC_FOUND) +target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) endif() target_link_libraries(${EXECUTABLE} devcrypto) diff --git a/libweb3jsonrpc/CMakeLists.txt b/libweb3jsonrpc/CMakeLists.txt index 9925b9026..133471d18 100644 --- a/libweb3jsonrpc/CMakeLists.txt +++ b/libweb3jsonrpc/CMakeLists.txt @@ -22,8 +22,8 @@ target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_COMMON_LIBRARY}) target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_SERVER_LIBRARY}) -if (MINIUPNPC_LS) - target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) +if (MINIUPNPC_FOUND) + target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) endif() target_link_libraries(${EXECUTABLE} webthree) diff --git a/libwebthree/CMakeLists.txt b/libwebthree/CMakeLists.txt index 2e305a5be..09fe7f736 100644 --- a/libwebthree/CMakeLists.txt +++ b/libwebthree/CMakeLists.txt @@ -19,8 +19,8 @@ endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) -if(MINIUPNPC_LS) -target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) +if(MINIUPNPC_FOUND) +target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) endif() target_link_libraries(${EXECUTABLE} ethereum) diff --git a/libwhisper/CMakeLists.txt b/libwhisper/CMakeLists.txt index 51908ffcf..3ab2f6097 100644 --- a/libwhisper/CMakeLists.txt +++ b/libwhisper/CMakeLists.txt @@ -19,8 +19,8 @@ endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) -if(MINIUPNPC_LS) -target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) +if(MINIUPNPC_FOUND) +target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) endif() target_link_libraries(${EXECUTABLE} ethcore) diff --git a/neth/CMakeLists.txt b/neth/CMakeLists.txt index 46195a1eb..4dd49874d 100644 --- a/neth/CMakeLists.txt +++ b/neth/CMakeLists.txt @@ -14,8 +14,8 @@ target_link_libraries(${EXECUTABLE} webthree) target_link_libraries(${EXECUTABLE} ethereum) target_link_libraries(${EXECUTABLE} secp256k1) target_link_libraries(${EXECUTABLE} gmp) -if(MINIUPNPC_LS) -target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) +if(MINIUPNPC_FOUND) +target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) if(JSON_RPC_CPP_FOUND) From d2344f5b36a4553558d24bb90d7ef2ff2e70a7a9 Mon Sep 17 00:00:00 2001 From: debris Date: Mon, 8 Dec 2014 15:03:40 +0100 Subject: [PATCH 091/277] common changes on windows --- cmake/EthDependencies.cmake | 9 ++++++--- secp256k1/CMakeLists.txt | 23 +++++++++++------------ 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 77cd3bfe7..8a86e7095 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -11,8 +11,9 @@ set (CMAKE_PREFIX_PATH ${CMAKE_DEPENDENCY_INSTALL_DIR}) # TODO use proper version of windows SDK (32 vs 64) # TODO make it possible to use older versions of windows SDK (7.0+ should also work) # TODO it windows SDK is NOT FOUND, throw ERROR -if (${CMAKE_CXX_COMPILER_ID} MATCHES "MSVC") +if (WIN32) set (CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "C:/Program Files/Windows Kits/8.1/Lib/winv6.3/um/x86") + message(" - Found windows 8.1 SDK") #set (CMAKE_PREFIX_PATH "C:/Program Files/Windows Kits/8.1/Lib/winv6.3/um/x64") endif() @@ -65,8 +66,10 @@ endif() # TODO gmp package does not yet check for correct version number # TODO it is also not required in msvc build find_package (Gmp 6.0.0) -message(" - gmp Header: ${GMP_INCLUDE_DIR}") -message(" - gmp lib : ${GMP_LIBRARY}") +if (GMP_FOUND) + message(" - gmp Header: ${GMP_INCLUDE_DIR}") + message(" - gmp lib : ${GMP_LIBRARY}") +endif() # TODO make headless client optional find_package (QT5Core REQUIRED) diff --git a/secp256k1/CMakeLists.txt b/secp256k1/CMakeLists.txt index f02bba238..230bf76b9 100644 --- a/secp256k1/CMakeLists.txt +++ b/secp256k1/CMakeLists.txt @@ -6,7 +6,16 @@ set(CMAKE_ASM_COMPILER "yasm") set(EXECUTABLE secp256k1) file(GLOB HEADERS "*.h") -if (${CMAKE_CXX_COMPILER_ID} MATCHES "MSVC") +if (APPLE OR UNIX) + + if (ETH_STATIC) + add_library(${EXECUTABLE} STATIC ${EXECUTABLE}.c field_5x52_asm.asm) + else() + add_library(${EXECUTABLE} SHARED ${EXECUTABLE}.c field_5x52_asm.asm) + endif() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -DUSE_FIELD_GMP -DUSE_NUM_GMP -DUSE_FIELD_INV_NUM") + target_link_libraries(${EXECUTABLE} ${GMP_LIBRARY}) +else() include_directories(${Boost_INCLUDE_DIRS}) if(ETH_STATIC) @@ -17,17 +26,7 @@ if (${CMAKE_CXX_COMPILER_ID} MATCHES "MSVC") # /TP - compile project as cpp project set_target_properties(${EXECUTABLE} PROPERTIES COMPILE_FLAGS "/TP") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUSE_NUM_BOOST -DUSE_FIELD_10X26 -DUSE_FIELD_INV_BUILTIN") - -elseif (APPLE OR UNIX) - - if (ETH_STATIC) - add_library(${EXECUTABLE} STATIC ${EXECUTABLE}.c field_5x52_asm.asm) - else() - add_library(${EXECUTABLE} SHARED ${EXECUTABLE}.c field_5x52_asm.asm) - endif() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -DUSE_FIELD_GMP -DUSE_NUM_GMP -DUSE_FIELD_INV_NUM") - target_link_libraries(${EXECUTABLE} ${GMP_LIBRARY}) - + endif() install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) From 7e44c34491a62cba5ecef5253404e0a25241a74b Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 8 Dec 2014 15:41:22 +0100 Subject: [PATCH 092/277] - manage Debugger states calculation in a separate thread (avoid blocking the UI) --- mix/AssemblyDebuggerCtrl.cpp | 25 +++++++++++++++++++------ mix/AssemblyDebuggerCtrl.h | 8 ++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/mix/AssemblyDebuggerCtrl.cpp b/mix/AssemblyDebuggerCtrl.cpp index 6e2b11e70..4d293cd8d 100644 --- a/mix/AssemblyDebuggerCtrl.cpp +++ b/mix/AssemblyDebuggerCtrl.cpp @@ -17,6 +17,7 @@ * display opcode debugging. */ +#include #include #include #include @@ -31,6 +32,9 @@ using namespace dev::mix; AssemblyDebuggerCtrl::AssemblyDebuggerCtrl(QTextDocument* _doc): Extension(ExtensionDisplayBehavior::ModalDialog) { + qRegisterMetaType(); + connect(this, SIGNAL(dataAvailable(QList, AssemblyDebuggerData)), + this, SLOT(updateGUI(QList, AssemblyDebuggerData)), Qt::QueuedConnection); m_modelDebugger = std::unique_ptr(new AssemblyDebuggerModel); m_doc = _doc; } @@ -56,6 +60,9 @@ void AssemblyDebuggerCtrl::keyPressed(int _key) if (_key == Qt::Key_F5) { + QString code = m_doc->toPlainText(); + QtConcurrent::run([this, code](){ + if (!m_modelDebugger->compile(m_doc->toPlainText())) { AppContext::getInstance()->displayMessageDialog("debugger","compilation failed"); @@ -76,10 +83,16 @@ void AssemblyDebuggerCtrl::keyPressed(int _key) s->setState(debuggingContent.states.at(i)); wStates.append(s); } - std::tuple, QQMLMap*> code = DebuggingStateWrapper::getHumanReadableCode(debuggingContent.executionCode, this); - AppContext::getInstance()->appEngine()->rootContext()->setContextProperty("debugStates", QVariant::fromValue(wStates)); - AppContext::getInstance()->appEngine()->rootContext()->setContextProperty("humanReadableExecutionCode", QVariant::fromValue(std::get<0>(code))); - AppContext::getInstance()->appEngine()->rootContext()->setContextProperty("bytesCodeMapping", QVariant::fromValue(std::get<1>(code))); - this->addContentOn(this); - }; + AssemblyDebuggerData code = DebuggingStateWrapper::getHumanReadableCode(debuggingContent.executionCode, this); + emit dataAvailable(wStates, code); + }); + } +} + +void AssemblyDebuggerCtrl::updateGUI(QList _wStates, AssemblyDebuggerData _code) +{ + AppContext::getInstance()->appEngine()->rootContext()->setContextProperty("debugStates", QVariant::fromValue(_wStates)); + AppContext::getInstance()->appEngine()->rootContext()->setContextProperty("humanReadableExecutionCode", QVariant::fromValue(std::get<0>(_code))); + AppContext::getInstance()->appEngine()->rootContext()->setContextProperty("bytesCodeMapping", QVariant::fromValue(std::get<1>(_code))); + this->addContentOn(this); } diff --git a/mix/AssemblyDebuggerCtrl.h b/mix/AssemblyDebuggerCtrl.h index a1642cc14..66256e472 100644 --- a/mix/AssemblyDebuggerCtrl.h +++ b/mix/AssemblyDebuggerCtrl.h @@ -25,6 +25,9 @@ #include "ConstantCompilationModel.h" #include "AssemblyDebuggerModel.h" +using AssemblyDebuggerData = std::tuple, dev::mix::QQMLMap*>; +Q_DECLARE_METATYPE(AssemblyDebuggerData) + namespace dev { @@ -48,6 +51,11 @@ private: public Q_SLOTS: void keyPressed(int); + void updateGUI(QList _wStates, AssemblyDebuggerData _code); + +signals: + void dataAvailable(QList _wStates, AssemblyDebuggerData _code); + }; } From 0d58c2b664d880253d93a1ec0b10c36f3ee03f6b Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 8 Dec 2014 16:53:07 +0100 Subject: [PATCH 093/277] - delete code comment (code used to resolve name using NameReg contract) --- libdevcore/CommonJS.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libdevcore/CommonJS.cpp b/libdevcore/CommonJS.cpp index 800bd06c8..8d8638da5 100644 --- a/libdevcore/CommonJS.cpp +++ b/libdevcore/CommonJS.cpp @@ -116,11 +116,6 @@ Address fromString(std::string _sn) return Address(fromHex(_sn)); else return Address(); - //we try to resolve the recipient adress using nameReg contract state - /*const Address c_config = Address("661005d2720d855f1d9976f88bb10c1a3398c77f"); //NameReg contract - if (h160 nameReg = (u160)ethClient->stateAt(c_config, 0)) - if (h256 a = ethClient->stateAt(nameReg, n)) - return right160(a);*/ } From 6030db73f771bc6edb8dcb4837464ffa5456df7b Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 8 Dec 2014 17:42:47 +0100 Subject: [PATCH 094/277] - Bug fix (failed compilation alert was loaded in a separate thread). - Coding Standards. - Add DebuggingStatusResult in AssemblyDebuggerCtrl --- mix/AssemblyDebuggerCtrl.cpp | 25 ++++++++++++++++--------- mix/AssemblyDebuggerCtrl.h | 11 +++++++++-- mix/AssemblyDebuggerModel.cpp | 4 ++-- mix/DebuggingStateWrapper.h | 4 ++-- mix/KeyEventManager.h | 6 +++--- mix/TransactionBuilder.cpp | 4 ++-- 6 files changed, 34 insertions(+), 20 deletions(-) diff --git a/mix/AssemblyDebuggerCtrl.cpp b/mix/AssemblyDebuggerCtrl.cpp index 4d293cd8d..e48aa9138 100644 --- a/mix/AssemblyDebuggerCtrl.cpp +++ b/mix/AssemblyDebuggerCtrl.cpp @@ -33,8 +33,9 @@ using namespace dev::mix; AssemblyDebuggerCtrl::AssemblyDebuggerCtrl(QTextDocument* _doc): Extension(ExtensionDisplayBehavior::ModalDialog) { qRegisterMetaType(); - connect(this, SIGNAL(dataAvailable(QList, AssemblyDebuggerData)), - this, SLOT(updateGUI(QList, AssemblyDebuggerData)), Qt::QueuedConnection); + qRegisterMetaType(); + connect(this, SIGNAL(dataAvailable(bool, DebuggingStatusResult, QList, AssemblyDebuggerData)), + this, SLOT(updateGUI(bool, DebuggingStatusResult, QList, AssemblyDebuggerData)), Qt::QueuedConnection); m_modelDebugger = std::unique_ptr(new AssemblyDebuggerModel); m_doc = _doc; } @@ -65,7 +66,7 @@ void AssemblyDebuggerCtrl::keyPressed(int _key) if (!m_modelDebugger->compile(m_doc->toPlainText())) { - AppContext::getInstance()->displayMessageDialog("debugger","compilation failed"); + emit dataAvailable(false, DebuggingStatusResult::Compilationfailed); return; } @@ -84,15 +85,21 @@ void AssemblyDebuggerCtrl::keyPressed(int _key) wStates.append(s); } AssemblyDebuggerData code = DebuggingStateWrapper::getHumanReadableCode(debuggingContent.executionCode, this); - emit dataAvailable(wStates, code); + emit dataAvailable(true, DebuggingStatusResult::Ok, wStates, code); }); } } -void AssemblyDebuggerCtrl::updateGUI(QList _wStates, AssemblyDebuggerData _code) +void AssemblyDebuggerCtrl::updateGUI(bool success, DebuggingStatusResult reason, QList _wStates, AssemblyDebuggerData _code) { - AppContext::getInstance()->appEngine()->rootContext()->setContextProperty("debugStates", QVariant::fromValue(_wStates)); - AppContext::getInstance()->appEngine()->rootContext()->setContextProperty("humanReadableExecutionCode", QVariant::fromValue(std::get<0>(_code))); - AppContext::getInstance()->appEngine()->rootContext()->setContextProperty("bytesCodeMapping", QVariant::fromValue(std::get<1>(_code))); - this->addContentOn(this); + Q_UNUSED(reason); + if (success) + { + AppContext::getInstance()->appEngine()->rootContext()->setContextProperty("debugStates", QVariant::fromValue(_wStates)); + AppContext::getInstance()->appEngine()->rootContext()->setContextProperty("humanReadableExecutionCode", QVariant::fromValue(std::get<0>(_code))); + AppContext::getInstance()->appEngine()->rootContext()->setContextProperty("bytesCodeMapping", QVariant::fromValue(std::get<1>(_code))); + this->addContentOn(this); + } + else + AppContext::getInstance()->displayMessageDialog("debugger","compilation failed"); } diff --git a/mix/AssemblyDebuggerCtrl.h b/mix/AssemblyDebuggerCtrl.h index 66256e472..0c092c46d 100644 --- a/mix/AssemblyDebuggerCtrl.h +++ b/mix/AssemblyDebuggerCtrl.h @@ -26,7 +26,14 @@ #include "AssemblyDebuggerModel.h" using AssemblyDebuggerData = std::tuple, dev::mix::QQMLMap*>; +enum DebuggingStatusResult +{ + Ok, + Compilationfailed +}; + Q_DECLARE_METATYPE(AssemblyDebuggerData) +Q_DECLARE_METATYPE(DebuggingStatusResult) namespace dev { @@ -51,10 +58,10 @@ private: public Q_SLOTS: void keyPressed(int); - void updateGUI(QList _wStates, AssemblyDebuggerData _code); + void updateGUI(bool success, DebuggingStatusResult reason, QList _wStates = QList(), AssemblyDebuggerData _code = AssemblyDebuggerData()); signals: - void dataAvailable(QList _wStates, AssemblyDebuggerData _code); + void dataAvailable(bool success, DebuggingStatusResult reason, QList _wStates = QList(), AssemblyDebuggerData _code = AssemblyDebuggerData()); }; diff --git a/mix/AssemblyDebuggerModel.cpp b/mix/AssemblyDebuggerModel.cpp index aa9795d53..bcf58835c 100644 --- a/mix/AssemblyDebuggerModel.cpp +++ b/mix/AssemblyDebuggerModel.cpp @@ -81,11 +81,11 @@ DebuggingContent AssemblyDebuggerModel::getContractInitiationDebugStates(dev::by DebuggingContent AssemblyDebuggerModel::getContractInitiationDebugStates(dev::u256 _value, dev::u256 _gasPrice, dev::u256 _gas, - QString code, + QString _code, KeyPair _key) { ConstantCompilationModel compiler; - CompilerResult res = compiler.compile(code); + CompilerResult res = compiler.compile(_code); if (!res.success) { DebuggingContent r; diff --git a/mix/DebuggingStateWrapper.h b/mix/DebuggingStateWrapper.h index df3b8ccce..89f90bfbd 100644 --- a/mix/DebuggingStateWrapper.h +++ b/mix/DebuggingStateWrapper.h @@ -111,7 +111,7 @@ class DebuggingStateWrapper: public QObject Q_PROPERTY(QStringList levels READ levels) public: - DebuggingStateWrapper(bytes _code, bytes _data, QObject* parent): QObject(parent), m_code(_code), m_data(_data) {} + DebuggingStateWrapper(bytes _code, bytes _data, QObject* _parent): QObject(_parent), m_code(_code), m_data(_data) {} int step() { return (int)m_state.steps; } int curPC() { return (int)m_state.curPC; } int gasCost() { return (int)m_state.gasCost; } @@ -125,7 +125,7 @@ public: QStringList levels(); DebuggingState state() { return m_state; } void setState(DebuggingState _state) { m_state = _state; } - static std::tuple, QQMLMap*> getHumanReadableCode(bytes const& code, QObject* _objUsedAsParent); + static std::tuple, QQMLMap*> getHumanReadableCode(bytes const& _code, QObject* _objUsedAsParent); private: DebuggingState m_state; diff --git a/mix/KeyEventManager.h b/mix/KeyEventManager.h index ecd768c4c..32ee5e867 100644 --- a/mix/KeyEventManager.h +++ b/mix/KeyEventManager.h @@ -30,13 +30,13 @@ class KeyEventManager: public QObject public: KeyEventManager() {} - void registerEvent(const QObject* receiver, const char* slot); - void unRegisterEvent(QObject* receiver); + void registerEvent(const QObject* _receiver, const char* _slot); + void unRegisterEvent(QObject* _receiver); signals: void onKeyPressed(int); public Q_SLOTS: - void keyPressed(QVariant event); + void keyPressed(QVariant _event); }; diff --git a/mix/TransactionBuilder.cpp b/mix/TransactionBuilder.cpp index bb7cda939..68eecf10b 100644 --- a/mix/TransactionBuilder.cpp +++ b/mix/TransactionBuilder.cpp @@ -33,8 +33,8 @@ Transaction TransactionBuilder::getCreationTransaction(u256 _value, u256 _gasPri } Transaction TransactionBuilder::getBasicTransaction(u256 _value, u256 _gasPrice, u256 _gas, - QString address, bytes _data, u256 _nonce, Secret _secret) const + QString _address, bytes _data, u256 _nonce, Secret _secret) const { - return Transaction(_value, _gasPrice, _gas, dev::fromString(address.toStdString()), _data, _nonce, _secret); + return Transaction(_value, _gasPrice, _gas, dev::fromString(_address.toStdString()), _data, _nonce, _secret); } From c014442517775c96350058d510b6c1f3d78ba9da Mon Sep 17 00:00:00 2001 From: debris Date: Mon, 8 Dec 2014 18:27:01 +0100 Subject: [PATCH 095/277] alethzero working on windows! --- alethzero/CMakeLists.txt | 5 ++--- alethzero/MainWin.cpp | 15 --------------- cmake/EthCompilerSettings.cmake | 1 + libdevcrypto/CMakeLists.txt | 2 +- mix/CMakeLists.txt | 3 +-- 5 files changed, 5 insertions(+), 21 deletions(-) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index a1177a0a3..07500390b 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -34,11 +34,10 @@ else () add_executable(${EXECUTABLE} Main.ui ${SRC_LIST} ${HEADERS}) endif () +add_dependencies(${EXECUTABLE} BuildInfo.h) + qt5_use_modules(${EXECUTABLE} Core) target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES}) -#target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) -#target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_COMMON_LIBRARY}) -#target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_SERVER_LIBRARY}) target_link_libraries(${EXECUTABLE} webthree) target_link_libraries(${EXECUTABLE} qethereum) target_link_libraries(${EXECUTABLE} ethereum) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index f7ae09498..f6ecf40a1 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -2240,18 +2240,3 @@ void Main::refreshWhispers() ui->whispers->addItem(item); } } - -// extra bits needed to link on VS -#ifdef _MSC_VER - -// include moc file, ofuscated to hide from automoc -#include\ -"moc_MainWin.cpp" - -#include\ -"moc_MiningView.cpp" - -#include\ -"moc_DownloadView.cpp" - -#endif diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index ba24b62e2..d821067a8 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -19,6 +19,7 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # specify Exception Handling Model in msvc + set(CMAKE_C_FLAGS "/EHsc") set(CMAKE_CXX_FLAGS "/EHsc") # windows likes static set(ETH_STATIC 1) diff --git a/libdevcrypto/CMakeLists.txt b/libdevcrypto/CMakeLists.txt index bf564e915..d2db758af 100644 --- a/libdevcrypto/CMakeLists.txt +++ b/libdevcrypto/CMakeLists.txt @@ -18,7 +18,7 @@ endif() target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY_RELEASE}) target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) -target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) +target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARY}) target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} secp256k1) diff --git a/mix/CMakeLists.txt b/mix/CMakeLists.txt index aa1f8cc02..f700b0dec 100644 --- a/mix/CMakeLists.txt +++ b/mix/CMakeLists.txt @@ -34,10 +34,9 @@ else () add_executable(${EXECUTEABLE} ${SRC_LIST} ${HEADERS} ${UI_RESOURCES}) endif () -#qt5_use_modules(${EXECUTEABLE} Core Gui Widgets Network WebKit WebKitWidgets) target_link_libraries(${EXECUTEABLE} Qt5::Core) target_link_libraries(${EXECUTEABLE} Qt5::Gui) -target_link_libraries(${EXECUTEABLE} webthree qethereum ethereum evm ethcore devcrypto secp256k1 ${CRYPTOPP_LS} serpent lll solidity evmcore devcore web3jsonrpc jsqrc) +target_link_libraries(${EXECUTEABLE} webthree qethereum ethereum evm ethcore devcrypto secp256k1 serpent lll solidity evmcore devcore web3jsonrpc jsqrc) if (APPLE) # First have qt5 install plugins and frameworks From 421506a8695b39ab50743eb386c7f160f8bcf360 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 8 Dec 2014 19:49:44 +0100 Subject: [PATCH 096/277] - Coding Standards. - Q_SLOTS => slots. - https://github.com/ethereum/cpp-ethereum/issues/557 => replace by 8 spaces instead of 4. - ref to QtQuick 2.2 instead of 2.3 --- mix/AppContext.h | 1 - mix/AssemblyDebuggerCtrl.cpp | 4 ++-- mix/AssemblyDebuggerCtrl.h | 3 +-- mix/AssemblyDebuggerModel.h | 1 - mix/CodeEditorExtensionManager.cpp | 2 -- mix/CodeEditorExtensionManager.h | 1 - mix/ConstantCompilationCtrl.cpp | 2 +- mix/ConstantCompilationCtrl.h | 3 +-- mix/ConstantCompilationModel.h | 1 - mix/DebuggingStateWrapper.cpp | 1 - mix/DebuggingStateWrapper.h | 1 - mix/Extension.h | 1 - mix/KeyEventManager.h | 2 +- mix/MixApplication.h | 1 - mix/TransactionBuilder.h | 1 - mix/qml/BasicMessage.qml | 2 +- mix/qml/Debugger.qml | 2 +- mix/qml/MainContent.qml | 2 +- 18 files changed, 9 insertions(+), 22 deletions(-) diff --git a/mix/AppContext.h b/mix/AppContext.h index da7bf9a8d..0016ab3be 100644 --- a/mix/AppContext.h +++ b/mix/AppContext.h @@ -33,7 +33,6 @@ namespace dev { - namespace mix { diff --git a/mix/AssemblyDebuggerCtrl.cpp b/mix/AssemblyDebuggerCtrl.cpp index e48aa9138..18e5802af 100644 --- a/mix/AssemblyDebuggerCtrl.cpp +++ b/mix/AssemblyDebuggerCtrl.cpp @@ -58,11 +58,11 @@ void AssemblyDebuggerCtrl::start() const void AssemblyDebuggerCtrl::keyPressed(int _key) { - if (_key == Qt::Key_F5) { QString code = m_doc->toPlainText(); - QtConcurrent::run([this, code](){ + QtConcurrent::run([this, code]() + { if (!m_modelDebugger->compile(m_doc->toPlainText())) { diff --git a/mix/AssemblyDebuggerCtrl.h b/mix/AssemblyDebuggerCtrl.h index 0c092c46d..1976b2d64 100644 --- a/mix/AssemblyDebuggerCtrl.h +++ b/mix/AssemblyDebuggerCtrl.h @@ -37,7 +37,6 @@ Q_DECLARE_METATYPE(DebuggingStatusResult) namespace dev { - namespace mix { @@ -56,7 +55,7 @@ private: std::unique_ptr m_modelDebugger; QTextDocument* m_doc; -public Q_SLOTS: +public slots: void keyPressed(int); void updateGUI(bool success, DebuggingStatusResult reason, QList _wStates = QList(), AssemblyDebuggerData _code = AssemblyDebuggerData()); diff --git a/mix/AssemblyDebuggerModel.h b/mix/AssemblyDebuggerModel.h index c0941dc8f..3ed6818bc 100644 --- a/mix/AssemblyDebuggerModel.h +++ b/mix/AssemblyDebuggerModel.h @@ -28,7 +28,6 @@ namespace dev { - namespace mix { diff --git a/mix/CodeEditorExtensionManager.cpp b/mix/CodeEditorExtensionManager.cpp index 78b0f0a7f..1b2a9cc3c 100644 --- a/mix/CodeEditorExtensionManager.cpp +++ b/mix/CodeEditorExtensionManager.cpp @@ -70,9 +70,7 @@ void CodeEditorExtensionManager::initExtension(std::shared_ptr _ext) try { if (_ext->getDisplayBehavior() == ExtensionDisplayBehavior::Tab) - { _ext->addTabOn(m_tabView); - } } catch (...) { diff --git a/mix/CodeEditorExtensionManager.h b/mix/CodeEditorExtensionManager.h index 8e8501bc9..84ce9af92 100644 --- a/mix/CodeEditorExtensionManager.h +++ b/mix/CodeEditorExtensionManager.h @@ -30,7 +30,6 @@ namespace dev { - namespace mix { diff --git a/mix/ConstantCompilationCtrl.cpp b/mix/ConstantCompilationCtrl.cpp index 771387656..8b0577d93 100644 --- a/mix/ConstantCompilationCtrl.cpp +++ b/mix/ConstantCompilationCtrl.cpp @@ -59,7 +59,7 @@ void ConstantCompilationCtrl::compile() resetOutPut(); return; } - CompilerResult res = m_compilationModel->compile(m_editor->toPlainText().replace("\t", " ")); + CompilerResult res = m_compilationModel->compile(m_editor->toPlainText().replace("\t", " ")); writeOutPut(res); } diff --git a/mix/ConstantCompilationCtrl.h b/mix/ConstantCompilationCtrl.h index 446838d39..7cde63a05 100644 --- a/mix/ConstantCompilationCtrl.h +++ b/mix/ConstantCompilationCtrl.h @@ -25,7 +25,6 @@ namespace dev { - namespace mix { @@ -46,7 +45,7 @@ private: void writeOutPut(CompilerResult const&); void resetOutPut(); -public Q_SLOTS: +public slots: void compile(); }; diff --git a/mix/ConstantCompilationModel.h b/mix/ConstantCompilationModel.h index 465cba285..4c161ec09 100644 --- a/mix/ConstantCompilationModel.h +++ b/mix/ConstantCompilationModel.h @@ -27,7 +27,6 @@ namespace dev { - namespace mix { diff --git a/mix/DebuggingStateWrapper.cpp b/mix/DebuggingStateWrapper.cpp index 2dde93520..89d9892ac 100644 --- a/mix/DebuggingStateWrapper.cpp +++ b/mix/DebuggingStateWrapper.cpp @@ -90,7 +90,6 @@ QString DebuggingStateWrapper::debugMemory() QString DebuggingStateWrapper::debugCallData() { - return QString::fromStdString(memDump(m_data, 16, false)); } diff --git a/mix/DebuggingStateWrapper.h b/mix/DebuggingStateWrapper.h index 89f90bfbd..09089fe58 100644 --- a/mix/DebuggingStateWrapper.h +++ b/mix/DebuggingStateWrapper.h @@ -29,7 +29,6 @@ namespace dev { - namespace mix { diff --git a/mix/Extension.h b/mix/Extension.h index b697af58b..b6a65bb5f 100644 --- a/mix/Extension.h +++ b/mix/Extension.h @@ -24,7 +24,6 @@ namespace dev { - namespace mix { diff --git a/mix/KeyEventManager.h b/mix/KeyEventManager.h index 32ee5e867..f3343cc45 100644 --- a/mix/KeyEventManager.h +++ b/mix/KeyEventManager.h @@ -36,7 +36,7 @@ public: signals: void onKeyPressed(int); -public Q_SLOTS: +public slots: void keyPressed(QVariant _event); }; diff --git a/mix/MixApplication.h b/mix/MixApplication.h index fdc506268..d927f2e07 100644 --- a/mix/MixApplication.h +++ b/mix/MixApplication.h @@ -27,7 +27,6 @@ namespace dev { - namespace mix { diff --git a/mix/TransactionBuilder.h b/mix/TransactionBuilder.h index 99f65b024..9ad929d38 100644 --- a/mix/TransactionBuilder.h +++ b/mix/TransactionBuilder.h @@ -25,7 +25,6 @@ namespace dev { - namespace mix { diff --git a/mix/qml/BasicMessage.qml b/mix/qml/BasicMessage.qml index 14ddbcf0d..0678c9b54 100644 --- a/mix/qml/BasicMessage.qml +++ b/mix/qml/BasicMessage.qml @@ -1,4 +1,4 @@ -import QtQuick 2.3 +import QtQuick 2.2 import QtQuick.Controls.Styles 1.2 import QtQuick.Controls 1.2 import QtQuick.Dialogs 1.2 diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml index 6802f57df..e895d1ada 100644 --- a/mix/qml/Debugger.qml +++ b/mix/qml/Debugger.qml @@ -1,4 +1,4 @@ -import QtQuick 2.3 +import QtQuick 2.2 import QtQuick.Controls.Styles 1.2 import QtQuick.Controls 1.2 import QtQuick.Dialogs 1.2 diff --git a/mix/qml/MainContent.qml b/mix/qml/MainContent.qml index 821b48913..1da48a1c8 100644 --- a/mix/qml/MainContent.qml +++ b/mix/qml/MainContent.qml @@ -1,4 +1,4 @@ -import QtQuick 2.3 +import QtQuick 2.2 import QtQuick.Controls 1.2 import QtQuick.Layouts 1.0 import QtQuick.Controls.Styles 1.2 From c9bf5fcd7c6fef8fba3982f853c429cbf16403cf Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 8 Dec 2014 21:32:05 +0100 Subject: [PATCH 097/277] - Instruction.h: add functions "getInstructionNumber" - AssemblyDebuggerCtrl add members AppContext, QQMLApplicationEngine --- libevmcore/Instruction.h | 18 ++++++++++++++++++ mix/AssemblyDebuggerCtrl.cpp | 12 +++++++----- mix/AssemblyDebuggerCtrl.h | 3 +++ mix/DebuggingStateWrapper.cpp | 3 ++- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/libevmcore/Instruction.h b/libevmcore/Instruction.h index f8a0478f1..555dbf0ea 100644 --- a/libevmcore/Instruction.h +++ b/libevmcore/Instruction.h @@ -173,6 +173,24 @@ enum class Instruction: uint8_t SUICIDE = 0xff ///< halt execution and register account for later deletion }; +/// @returns the number of PUSH Instruction _inst +inline unsigned getPushNumber(Instruction _inst) +{ + return (byte)_inst - unsigned(Instruction::PUSH1) + 1; +} + +/// @returns the number of DUP Instruction _inst +inline unsigned getDupNumber(Instruction _inst) +{ + return (byte)_inst - unsigned(Instruction::DUP1) + 1; +} + +/// @returns the number of SWAP Instruction _inst +inline unsigned getSwapNumber(Instruction _inst) +{ + return (byte)_inst - unsigned(Instruction::SWAP1) + 1; +} + /// @returns the PUSH<_number> instruction inline Instruction pushInstruction(unsigned _number) { diff --git a/mix/AssemblyDebuggerCtrl.cpp b/mix/AssemblyDebuggerCtrl.cpp index 18e5802af..1fdb9403e 100644 --- a/mix/AssemblyDebuggerCtrl.cpp +++ b/mix/AssemblyDebuggerCtrl.cpp @@ -32,6 +32,8 @@ using namespace dev::mix; AssemblyDebuggerCtrl::AssemblyDebuggerCtrl(QTextDocument* _doc): Extension(ExtensionDisplayBehavior::ModalDialog) { + m_ctx = AppContext::getInstance(); + m_appEngine = m_ctx->appEngine(); qRegisterMetaType(); qRegisterMetaType(); connect(this, SIGNAL(dataAvailable(bool, DebuggingStatusResult, QList, AssemblyDebuggerData)), @@ -53,7 +55,7 @@ QString AssemblyDebuggerCtrl::title() const void AssemblyDebuggerCtrl::start() const { //start to listen on F5 - AppContext::getInstance()->getKeyEventManager()->registerEvent(this, SLOT(keyPressed(int))); + m_ctx->getKeyEventManager()->registerEvent(this, SLOT(keyPressed(int))); } void AssemblyDebuggerCtrl::keyPressed(int _key) @@ -95,11 +97,11 @@ void AssemblyDebuggerCtrl::updateGUI(bool success, DebuggingStatusResult reason, Q_UNUSED(reason); if (success) { - AppContext::getInstance()->appEngine()->rootContext()->setContextProperty("debugStates", QVariant::fromValue(_wStates)); - AppContext::getInstance()->appEngine()->rootContext()->setContextProperty("humanReadableExecutionCode", QVariant::fromValue(std::get<0>(_code))); - AppContext::getInstance()->appEngine()->rootContext()->setContextProperty("bytesCodeMapping", QVariant::fromValue(std::get<1>(_code))); + m_appEngine->rootContext()->setContextProperty("debugStates", QVariant::fromValue(_wStates)); + m_appEngine->rootContext()->setContextProperty("humanReadableExecutionCode", QVariant::fromValue(std::get<0>(_code))); + m_appEngine->rootContext()->setContextProperty("bytesCodeMapping", QVariant::fromValue(std::get<1>(_code))); this->addContentOn(this); } else - AppContext::getInstance()->displayMessageDialog("debugger","compilation failed"); + m_ctx->displayMessageDialog("debugger","compilation failed"); } diff --git a/mix/AssemblyDebuggerCtrl.h b/mix/AssemblyDebuggerCtrl.h index 1976b2d64..b4957ed85 100644 --- a/mix/AssemblyDebuggerCtrl.h +++ b/mix/AssemblyDebuggerCtrl.h @@ -24,6 +24,7 @@ #include "Extension.h" #include "ConstantCompilationModel.h" #include "AssemblyDebuggerModel.h" +#include "AppContext.h" using AssemblyDebuggerData = std::tuple, dev::mix::QQMLMap*>; enum DebuggingStatusResult @@ -54,6 +55,8 @@ public: private: std::unique_ptr m_modelDebugger; QTextDocument* m_doc; + AppContext* m_ctx; + QQmlApplicationEngine* m_appEngine; public slots: void keyPressed(int); diff --git a/mix/DebuggingStateWrapper.cpp b/mix/DebuggingStateWrapper.cpp index 89d9892ac..6328cce6b 100644 --- a/mix/DebuggingStateWrapper.cpp +++ b/mix/DebuggingStateWrapper.cpp @@ -23,6 +23,7 @@ #include #include #include +#include "libevmcore/Instruction.h" #include "libdevcore/CommonJS.h" #include "libdevcrypto/Common.h" #include "libevmcore/Instruction.h" @@ -48,7 +49,7 @@ std::tuple, QQMLMap*> DebuggingStateWrapper::getHumanReadableCod int line = i; if (b >= (byte)Instruction::PUSH1 && b <= (byte)Instruction::PUSH32) { - unsigned bc = b - (byte)Instruction::PUSH1 + 1; + unsigned bc = getPushNumber((Instruction)b); s = "PUSH 0x" + QString::fromStdString(toHex(bytesConstRef(&_code[i + 1], bc))); i += bc; } From dee70471980d59b3a8b97b677a1bd0051839984f Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 8 Dec 2014 21:56:17 +0100 Subject: [PATCH 098/277] - QQMLApplicationEngine and AppContext moved to Extension.h --- mix/AssemblyDebuggerCtrl.cpp | 2 -- mix/AssemblyDebuggerCtrl.h | 2 -- mix/DebuggingStateWrapper.cpp | 2 +- mix/Extension.cpp | 17 +++++++++++++++++ mix/Extension.h | 10 ++++++++-- 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/mix/AssemblyDebuggerCtrl.cpp b/mix/AssemblyDebuggerCtrl.cpp index 1fdb9403e..36318ccb7 100644 --- a/mix/AssemblyDebuggerCtrl.cpp +++ b/mix/AssemblyDebuggerCtrl.cpp @@ -32,8 +32,6 @@ using namespace dev::mix; AssemblyDebuggerCtrl::AssemblyDebuggerCtrl(QTextDocument* _doc): Extension(ExtensionDisplayBehavior::ModalDialog) { - m_ctx = AppContext::getInstance(); - m_appEngine = m_ctx->appEngine(); qRegisterMetaType(); qRegisterMetaType(); connect(this, SIGNAL(dataAvailable(bool, DebuggingStatusResult, QList, AssemblyDebuggerData)), diff --git a/mix/AssemblyDebuggerCtrl.h b/mix/AssemblyDebuggerCtrl.h index b4957ed85..e94cc4ce9 100644 --- a/mix/AssemblyDebuggerCtrl.h +++ b/mix/AssemblyDebuggerCtrl.h @@ -55,8 +55,6 @@ public: private: std::unique_ptr m_modelDebugger; QTextDocument* m_doc; - AppContext* m_ctx; - QQmlApplicationEngine* m_appEngine; public slots: void keyPressed(int); diff --git a/mix/DebuggingStateWrapper.cpp b/mix/DebuggingStateWrapper.cpp index 6328cce6b..2315cd5a8 100644 --- a/mix/DebuggingStateWrapper.cpp +++ b/mix/DebuggingStateWrapper.cpp @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file DebuggingStateWrapper.h +/** @file DebuggingStateWrapper.cpp * @author Yann yann@ethdev.com * @date 2014 * Used to translate c++ type (u256, bytes, ...) into friendly value (to be used by QML). diff --git a/mix/Extension.cpp b/mix/Extension.cpp index 410fe85ec..f9a8ad94d 100644 --- a/mix/Extension.cpp +++ b/mix/Extension.cpp @@ -25,6 +25,23 @@ using namespace dev; using namespace dev::mix; +Extension::Extension() +{ + init(); +} + +Extension::Extension(ExtensionDisplayBehavior _displayBehavior) +{ + init(); + m_displayBehavior = _displayBehavior; +} + +void Extension::init() +{ + m_ctx = AppContext::getInstance(); + m_appEngine = m_ctx->appEngine(); +} + void Extension::addTabOn(QObject* _view) { if (contentUrl() == "") diff --git a/mix/Extension.h b/mix/Extension.h index b6a65bb5f..4d6f4f084 100644 --- a/mix/Extension.h +++ b/mix/Extension.h @@ -21,6 +21,7 @@ #include #include +#include "AppContext.h" namespace dev { @@ -39,8 +40,8 @@ class Extension: public QObject Q_OBJECT public: - Extension() {} - Extension(ExtensionDisplayBehavior _displayBehavior) { m_displayBehavior = _displayBehavior; } + Extension(); + Extension(ExtensionDisplayBehavior _displayBehavior); virtual QString contentUrl() const { return ""; } virtual QString title() const { return ""; } virtual void start() const {} @@ -52,6 +53,11 @@ public: protected: QObject* m_view; ExtensionDisplayBehavior m_displayBehavior; + AppContext* m_ctx; + QQmlApplicationEngine* m_appEngine; + +private: + void init(); }; } From 5071446c6861757b592d54fa176b6f7497086072 Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 9 Dec 2014 00:58:02 +0100 Subject: [PATCH 099/277] msvc changes in tests, but tests not yet working there --- cmake/EthDependencies.cmake | 2 +- test/CMakeLists.txt | 36 ++++------------------------- test/jsonrpc.cpp | 5 +++- test/solidityEndToEndTest.cpp | 35 ++++++++++++++-------------- test/solidityExpressionCompiler.cpp | 3 +++ test/solidityJSONInterfaceTest.cpp | 2 +- test/solidityNatspecJSON.cpp | 2 +- 7 files changed, 33 insertions(+), 52 deletions(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 8a86e7095..fb2aafd47 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -90,7 +90,7 @@ if (${CMAKE_CXX_COMPILER_ID} MATCHES "MSVC") set(Boost_COMPILER -vc120) endif() -find_package(Boost 1.55.0 REQUIRED COMPONENTS thread date_time system regex chrono filesystem) +find_package(Boost 1.55.0 REQUIRED COMPONENTS thread date_time system regex chrono filesystem unit_test_framework) message(" - boost header: ${Boost_INCLUDE_DIRS}") message(" - boost lib : ${Boost_LIBRARIES}") diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 59eb34bc8..e27e0949d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -3,53 +3,27 @@ cmake_policy(SET CMP0015 NEW) aux_source_directory(. SRC_LIST) list(REMOVE_ITEM SRC_LIST "./createRandomTest.cpp") -include_directories(..) include_directories(${CRYPTOPP_INCLUDE_DIRS}) include_directories(${JSONCPP_INCLUDE_DIRS}) +include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) +include_directories(..) file(GLOB HEADERS "*.h") add_executable(testeth ${SRC_LIST} ${HEADERS}) add_executable(createRandomTest createRandomTest.cpp vm.cpp TestHelper.cpp) - target_link_libraries(testeth ethereum) target_link_libraries(testeth ethcore) target_link_libraries(testeth secp256k1) -target_link_libraries(testeth gmp) target_link_libraries(testeth solidity) target_link_libraries(testeth webthree) +target_link_libraries(testeth ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE}) -target_link_libraries(testeth ${CRYPTOPP_LIBRARIES}) - -if(JSON_RPC_CPP_FOUND) - target_link_libraries(testeth ${JSONCPP_LIBRARIES}) +if (JSON_RPC_CPP_FOUND) target_link_libraries(testeth web3jsonrpc) target_link_libraries(testeth ${JSON_RPC_CPP_CLIENT_LIBRARY}) endif() target_link_libraries(createRandomTest ethereum) target_link_libraries(createRandomTest ethcore) -target_link_libraries(createRandomTest boost_chrono) -target_link_libraries(createRandomTest boost_unit_test_framework) -target_link_libraries(createRandomTest ${CRYPTOPP_LIBRARIES}) - -if ("${TARGET_PLATFORM}" STREQUAL "w64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") - target_link_libraries(testeth boost_system-mt-s) - target_link_libraries(testeth boost_filesystem-mt-s) - target_link_libraries(testeth boost_thread_win32-mt-s) - target_link_libraries(testeth gcc) - target_link_libraries(testeth gdi32) - target_link_libraries(testeth ws2_32) - target_link_libraries(testeth mswsock) - target_link_libraries(testeth shlwapi) - target_link_libraries(testeth iphlpapi) - set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) -elseif (UNIX) - find_package(Boost 1.53 REQUIRED COMPONENTS unit_test_framework) -else () - target_link_libraries(testeth boost_system) - target_link_libraries(testeth boost_filesystem) - find_package(Threads REQUIRED) - target_link_libraries(testeth ${CMAKE_THREAD_LIBS_INIT}) -endif () +target_link_libraries(createRandomTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE}) diff --git a/test/jsonrpc.cpp b/test/jsonrpc.cpp index 3c1725388..5a9b94ebc 100644 --- a/test/jsonrpc.cpp +++ b/test/jsonrpc.cpp @@ -62,7 +62,7 @@ struct Setup web3->setIdealPeerCount(5); web3->ethereum()->setForceMining(true); - auto server = new jsonrpc::CorsHttpServer(8080); + auto server = new jsonrpc::HttpServer(8080); jsonrpcServer = unique_ptr(new WebThreeStubServer(*server, *web3, {})); jsonrpcServer->setIdentities({}); jsonrpcServer->StartListening(); @@ -302,8 +302,11 @@ BOOST_AUTO_TEST_CASE(contract_storage) Json::Value storage = jsonrpcClient->eth_storageAt(contractAddress); BOOST_CHECK_EQUAL(storage.getMemberNames().size(), 1); + // bracers are required, cause msvc couldnt handle this macro in for statement for (auto name: storage.getMemberNames()) + { BOOST_CHECK_EQUAL(storage[name].asString(), "0x03"); + } } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/solidityEndToEndTest.cpp b/test/solidityEndToEndTest.cpp index 9e02438e8..1ea9fe351 100644 --- a/test/solidityEndToEndTest.cpp +++ b/test/solidityEndToEndTest.cpp @@ -519,22 +519,23 @@ BOOST_AUTO_TEST_CASE(simple_mapping) " }\n" "}"; compileAndRun(sourceCode); - - BOOST_CHECK(callContractFunction(0, bytes({0x00})) == bytes({0x00})); - BOOST_CHECK(callContractFunction(0, bytes({0x01})) == bytes({0x00})); - BOOST_CHECK(callContractFunction(0, bytes({0xa7})) == bytes({0x00})); + + // msvc seems to have problems with initializer-list, when there is only 1 param in the list + BOOST_CHECK(callContractFunction(0, bytes(1, 0x00)) == bytes(1, 0x00)); + BOOST_CHECK(callContractFunction(0, bytes(1, 0x01)) == bytes(1, 0x00)); + BOOST_CHECK(callContractFunction(0, bytes(1, 0xa7)) == bytes(1, 0x00)); callContractFunction(1, bytes({0x01, 0xa1})); - BOOST_CHECK(callContractFunction(0, bytes({0x00})) == bytes({0x00})); - BOOST_CHECK(callContractFunction(0, bytes({0x01})) == bytes({0xa1})); - BOOST_CHECK(callContractFunction(0, bytes({0xa7})) == bytes({0x00})); + BOOST_CHECK(callContractFunction(0, bytes(1, 0x00)) == bytes(1, 0x00)); + BOOST_CHECK(callContractFunction(0, bytes(1, 0x01)) == bytes(1, 0xa1)); + BOOST_CHECK(callContractFunction(0, bytes(1, 0xa7)) == bytes(1, 0x00)); callContractFunction(1, bytes({0x00, 0xef})); - BOOST_CHECK(callContractFunction(0, bytes({0x00})) == bytes({0xef})); - BOOST_CHECK(callContractFunction(0, bytes({0x01})) == bytes({0xa1})); - BOOST_CHECK(callContractFunction(0, bytes({0xa7})) == bytes({0x00})); + BOOST_CHECK(callContractFunction(0, bytes(1, 0x00)) == bytes(1, 0xef)); + BOOST_CHECK(callContractFunction(0, bytes(1, 0x01)) == bytes(1, 0xa1)); + BOOST_CHECK(callContractFunction(0, bytes(1, 0xa7)) == bytes(1, 0x00)); callContractFunction(1, bytes({0x01, 0x05})); - BOOST_CHECK(callContractFunction(0, bytes({0x00})) == bytes({0xef})); - BOOST_CHECK(callContractFunction(0, bytes({0x01})) == bytes({0x05})); - BOOST_CHECK(callContractFunction(0, bytes({0xa7})) == bytes({0x00})); + BOOST_CHECK(callContractFunction(0, bytes(1, 0x00)) == bytes(1, 0xef)); + BOOST_CHECK(callContractFunction(0, bytes(1, 0x01)) == bytes(1, 0x05)); + BOOST_CHECK(callContractFunction(0, bytes(1, 0xa7)) == bytes(1, 0x00)); } BOOST_AUTO_TEST_CASE(mapping_state) @@ -702,9 +703,9 @@ BOOST_AUTO_TEST_CASE(structs) " }\n" "}\n"; compileAndRun(sourceCode); - BOOST_CHECK(callContractFunction(0) == bytes({0x00})); + BOOST_CHECK(callContractFunction(0) == bytes(1, 0x00)); BOOST_CHECK(callContractFunction(1) == bytes()); - BOOST_CHECK(callContractFunction(0) == bytes({0x01})); + BOOST_CHECK(callContractFunction(0) == bytes(1, 0x01)); } BOOST_AUTO_TEST_CASE(struct_reference) @@ -730,9 +731,9 @@ BOOST_AUTO_TEST_CASE(struct_reference) " }\n" "}\n"; compileAndRun(sourceCode); - BOOST_CHECK(callContractFunction(0) == bytes({0x00})); + BOOST_CHECK(callContractFunction(0) == bytes(1, 0x00)); BOOST_CHECK(callContractFunction(1) == bytes()); - BOOST_CHECK(callContractFunction(0) == bytes({0x01})); + BOOST_CHECK(callContractFunction(0) == bytes(1, 0x01)); } BOOST_AUTO_TEST_CASE(constructor) diff --git a/test/solidityExpressionCompiler.cpp b/test/solidityExpressionCompiler.cpp index 486b46ebb..c05db25d4 100644 --- a/test/solidityExpressionCompiler.cpp +++ b/test/solidityExpressionCompiler.cpp @@ -76,8 +76,11 @@ Declaration const& resolveDeclaration(vector const& _namespacedName, NameAndTypeResolver const& _resolver) { Declaration const* declaration = nullptr; + // bracers are required, cause msvc couldnt handle this macro in for statement for (string const& namePart: _namespacedName) + { BOOST_REQUIRE(declaration = _resolver.resolveName(namePart, declaration)); + } BOOST_REQUIRE(declaration); return *declaration; } diff --git a/test/solidityJSONInterfaceTest.cpp b/test/solidityJSONInterfaceTest.cpp index 487508bb9..c734009c3 100644 --- a/test/solidityJSONInterfaceTest.cpp +++ b/test/solidityJSONInterfaceTest.cpp @@ -22,7 +22,7 @@ #include #include -#include +#include #include namespace dev diff --git a/test/solidityNatspecJSON.cpp b/test/solidityNatspecJSON.cpp index f1795fe1c..d66d1294f 100644 --- a/test/solidityNatspecJSON.cpp +++ b/test/solidityNatspecJSON.cpp @@ -22,7 +22,7 @@ #include #include -#include +#include #include namespace dev From 49063af0494cc34dfe7393b1620f24b04061ef5a Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 9 Dec 2014 01:03:55 +0100 Subject: [PATCH 100/277] common changes in mix --- mix/CMakeLists.txt | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/mix/CMakeLists.txt b/mix/CMakeLists.txt index f700b0dec..bdb682a09 100644 --- a/mix/CMakeLists.txt +++ b/mix/CMakeLists.txt @@ -36,7 +36,20 @@ endif () target_link_libraries(${EXECUTEABLE} Qt5::Core) target_link_libraries(${EXECUTEABLE} Qt5::Gui) -target_link_libraries(${EXECUTEABLE} webthree qethereum ethereum evm ethcore devcrypto secp256k1 serpent lll solidity evmcore devcore web3jsonrpc jsqrc) +target_link_libraries(${EXECUTEABLE} webthree) +target_link_libraries(${EXECUTEABLE} qethereum) +target_link_libraries(${EXECUTEABLE} ethereum) +target_link_libraries(${EXECUTEABLE} evm) +target_link_libraries(${EXECUTEABLE} ethcore) +target_link_libraries(${EXECUTEABLE} devcrypto) +target_link_libraries(${EXECUTEABLE} secp256k1) +target_link_libraries(${EXECUTEABLE} serpent) +target_link_libraries(${EXECUTEABLE} lll) +target_link_libraries(${EXECUTEABLE} solidity) +target_link_libraries(${EXECUTEABLE} evmcore) +target_link_libraries(${EXECUTEABLE} devcore) +target_link_libraries(${EXECUTEABLE} web3jsonrpc) +target_link_libraries(${EXECUTEABLE} jsqrc) if (APPLE) # First have qt5 install plugins and frameworks From dbb724da9f331a9539427a93f4c055abcafcc887 Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 9 Dec 2014 01:05:37 +0100 Subject: [PATCH 101/277] removed windows dir --- windows/.gitattributes | 2 - windows/Alethzero.vcxproj | 311 --- windows/Alethzero.vcxproj.filters | 37 - windows/BuildInfo.lua | 25 - windows/Eth.vcxproj | 195 -- windows/Ethereum.sln | 191 -- windows/Ethereum.vcxproj.filters | 16 - windows/Exp.vcxproj | 195 -- windows/LibCryptoPP.vcxproj | 414 --- windows/LibEthereum.props | 35 - windows/LibEthereum.vcxproj | 571 ----- windows/LibEthereum.vcxproj.filters | 477 ---- windows/LibEthereum_Debug.props | 18 - windows/LibEthereum_Release.props | 14 - windows/LibLevelDB.vcxproj | 221 -- windows/LibLevelDB.vcxproj.filters | 246 -- windows/LibMiniUPnPc.vcxproj | 182 -- windows/LibQEthereum.props | 70 - windows/LibQEthereum.vcxproj | 204 -- windows/LibQEthereum.vcxproj.filters | 24 - windows/LibSecp256k1.vcxproj | 183 -- windows/LibSecp256k1.vcxproj.filters | 71 - windows/LibSerpent.vcxproj | 187 -- windows/LibSerpent.vcxproj.filters | 18 - windows/Lllc.vcxproj | 195 -- windows/Neth.vcxproj | 213 -- windows/Sc.vcxproj | 198 -- windows/TestEthereum.vcxproj | 194 -- windows/TestEthereum.vcxproj.filters | 38 - windows/TestSecp256k1.vcxproj | 171 -- windows/Walleth.vcxproj | 315 --- windows/Walleth.vcxproj.filters | 34 - windows/WinMain.cpp | 72 - windows/bootstrap.sh | 233 -- windows/compile_ethereum.bat | 14 - windows/compile_icu.bat | 11 - windows/compile_qt.bat | 51 - windows/include/LibLevelDB/port/port.h | 23 - windows/include/LibLevelDB/unistd.h | 0 .../include/LibMiniUPnPc/miniupnpcstrings.h | 14 - windows/moc.lua | 38 - windows/ncurses/include/ncurses/curses.h | 1675 ------------ windows/ncurses/include/ncurses/cursesapp.h | 176 -- windows/ncurses/include/ncurses/cursesf.h | 967 ------- windows/ncurses/include/ncurses/cursesm.h | 672 ----- windows/ncurses/include/ncurses/cursesp.h | 268 -- windows/ncurses/include/ncurses/cursesw.h | 1556 ----------- windows/ncurses/include/ncurses/cursslk.h | 238 -- windows/ncurses/include/ncurses/eti.h | 54 - windows/ncurses/include/ncurses/etip.h | 378 --- windows/ncurses/include/ncurses/form.h | 422 --- windows/ncurses/include/ncurses/menu.h | 260 -- windows/ncurses/include/ncurses/nc_tparm.h | 73 - windows/ncurses/include/ncurses/ncurses.h | 1675 ------------ windows/ncurses/include/ncurses/ncurses_dll.h | 86 - windows/ncurses/include/ncurses/panel.h | 85 - windows/ncurses/include/ncurses/term.h | 834 ------ windows/ncurses/include/ncurses/term_entry.h | 174 -- windows/ncurses/include/ncurses/termcap.h | 75 - windows/ncurses/include/ncurses/tic.h | 346 --- windows/ncurses/include/ncurses/unctrl.h | 67 - windows/ncurses/lib/Win32/libgcc_s_sjlj-1.dll | Bin 88085 -> 0 bytes windows/ncurses/lib/Win32/wform.dll | Bin 150757 -> 0 bytes windows/ncurses/lib/Win32/wform.lib | Bin 20764 -> 0 bytes windows/ncurses/lib/Win32/wmenu.dll | Bin 59968 -> 0 bytes windows/ncurses/lib/Win32/wmenu.lib | Bin 17014 -> 0 bytes windows/ncurses/lib/Win32/wncurses.dll | Bin 432882 -> 0 bytes windows/ncurses/lib/Win32/wncurses.lib | Bin 123366 -> 0 bytes windows/ncurses/lib/Win32/wpanel.dll | Bin 40517 -> 0 bytes windows/ncurses/lib/Win32/wpanel.lib | Bin 5050 -> 0 bytes windows/ncurses/lib/x64/wform.dll | Bin 164906 -> 0 bytes windows/ncurses/lib/x64/wform.lib | Bin 20002 -> 0 bytes windows/ncurses/lib/x64/wmenu.dll | Bin 67812 -> 0 bytes windows/ncurses/lib/x64/wmenu.lib | Bin 16184 -> 0 bytes windows/ncurses/lib/x64/wncurses.dll | Bin 470191 -> 0 bytes windows/ncurses/lib/x64/wncurses.lib | Bin 120128 -> 0 bytes windows/ncurses/lib/x64/wpanel.dll | Bin 45915 -> 0 bytes windows/ncurses/lib/x64/wpanel.lib | Bin 4828 -> 0 bytes .../icu/0001-Upgrade-projects-to-VS2013.patch | 2279 ----------------- ...0002-Qt-requires-U_CHARSET_IS_UTF8-1.patch | 26 - .../icu/0003-Add-minimal-icu.sln.patch | 71 - windows/qt_plugin_import.cpp | 4 - windows/stdafx.cpp | 21 - windows/stdafx.h | 60 - 84 files changed, 18263 deletions(-) delete mode 100644 windows/.gitattributes delete mode 100644 windows/Alethzero.vcxproj delete mode 100644 windows/Alethzero.vcxproj.filters delete mode 100644 windows/BuildInfo.lua delete mode 100644 windows/Eth.vcxproj delete mode 100644 windows/Ethereum.sln delete mode 100644 windows/Ethereum.vcxproj.filters delete mode 100644 windows/Exp.vcxproj delete mode 100644 windows/LibCryptoPP.vcxproj delete mode 100644 windows/LibEthereum.props delete mode 100644 windows/LibEthereum.vcxproj delete mode 100644 windows/LibEthereum.vcxproj.filters delete mode 100644 windows/LibEthereum_Debug.props delete mode 100644 windows/LibEthereum_Release.props delete mode 100644 windows/LibLevelDB.vcxproj delete mode 100644 windows/LibLevelDB.vcxproj.filters delete mode 100644 windows/LibMiniUPnPc.vcxproj delete mode 100644 windows/LibQEthereum.props delete mode 100644 windows/LibQEthereum.vcxproj delete mode 100644 windows/LibQEthereum.vcxproj.filters delete mode 100644 windows/LibSecp256k1.vcxproj delete mode 100644 windows/LibSecp256k1.vcxproj.filters delete mode 100644 windows/LibSerpent.vcxproj delete mode 100644 windows/LibSerpent.vcxproj.filters delete mode 100644 windows/Lllc.vcxproj delete mode 100644 windows/Neth.vcxproj delete mode 100644 windows/Sc.vcxproj delete mode 100644 windows/TestEthereum.vcxproj delete mode 100644 windows/TestEthereum.vcxproj.filters delete mode 100644 windows/TestSecp256k1.vcxproj delete mode 100644 windows/Walleth.vcxproj delete mode 100644 windows/Walleth.vcxproj.filters delete mode 100644 windows/WinMain.cpp delete mode 100644 windows/bootstrap.sh delete mode 100644 windows/compile_ethereum.bat delete mode 100644 windows/compile_icu.bat delete mode 100644 windows/compile_qt.bat delete mode 100644 windows/include/LibLevelDB/port/port.h delete mode 100644 windows/include/LibLevelDB/unistd.h delete mode 100644 windows/include/LibMiniUPnPc/miniupnpcstrings.h delete mode 100644 windows/moc.lua delete mode 100644 windows/ncurses/include/ncurses/curses.h delete mode 100644 windows/ncurses/include/ncurses/cursesapp.h delete mode 100644 windows/ncurses/include/ncurses/cursesf.h delete mode 100644 windows/ncurses/include/ncurses/cursesm.h delete mode 100644 windows/ncurses/include/ncurses/cursesp.h delete mode 100644 windows/ncurses/include/ncurses/cursesw.h delete mode 100644 windows/ncurses/include/ncurses/cursslk.h delete mode 100644 windows/ncurses/include/ncurses/eti.h delete mode 100644 windows/ncurses/include/ncurses/etip.h delete mode 100644 windows/ncurses/include/ncurses/form.h delete mode 100644 windows/ncurses/include/ncurses/menu.h delete mode 100644 windows/ncurses/include/ncurses/nc_tparm.h delete mode 100644 windows/ncurses/include/ncurses/ncurses.h delete mode 100644 windows/ncurses/include/ncurses/ncurses_dll.h delete mode 100644 windows/ncurses/include/ncurses/panel.h delete mode 100644 windows/ncurses/include/ncurses/term.h delete mode 100644 windows/ncurses/include/ncurses/term_entry.h delete mode 100644 windows/ncurses/include/ncurses/termcap.h delete mode 100644 windows/ncurses/include/ncurses/tic.h delete mode 100644 windows/ncurses/include/ncurses/unctrl.h delete mode 100644 windows/ncurses/lib/Win32/libgcc_s_sjlj-1.dll delete mode 100644 windows/ncurses/lib/Win32/wform.dll delete mode 100644 windows/ncurses/lib/Win32/wform.lib delete mode 100644 windows/ncurses/lib/Win32/wmenu.dll delete mode 100644 windows/ncurses/lib/Win32/wmenu.lib delete mode 100644 windows/ncurses/lib/Win32/wncurses.dll delete mode 100644 windows/ncurses/lib/Win32/wncurses.lib delete mode 100644 windows/ncurses/lib/Win32/wpanel.dll delete mode 100644 windows/ncurses/lib/Win32/wpanel.lib delete mode 100644 windows/ncurses/lib/x64/wform.dll delete mode 100644 windows/ncurses/lib/x64/wform.lib delete mode 100644 windows/ncurses/lib/x64/wmenu.dll delete mode 100644 windows/ncurses/lib/x64/wmenu.lib delete mode 100644 windows/ncurses/lib/x64/wncurses.dll delete mode 100644 windows/ncurses/lib/x64/wncurses.lib delete mode 100644 windows/ncurses/lib/x64/wpanel.dll delete mode 100644 windows/ncurses/lib/x64/wpanel.lib delete mode 100644 windows/patches/icu/0001-Upgrade-projects-to-VS2013.patch delete mode 100644 windows/patches/icu/0002-Qt-requires-U_CHARSET_IS_UTF8-1.patch delete mode 100644 windows/patches/icu/0003-Add-minimal-icu.sln.patch delete mode 100644 windows/qt_plugin_import.cpp delete mode 100644 windows/stdafx.cpp delete mode 100644 windows/stdafx.h diff --git a/windows/.gitattributes b/windows/.gitattributes deleted file mode 100644 index 48910107d..000000000 --- a/windows/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -*.vcxproj eol=crlf -*.props eol=crlf diff --git a/windows/Alethzero.vcxproj b/windows/Alethzero.vcxproj deleted file mode 100644 index 38dbd6265..000000000 --- a/windows/Alethzero.vcxproj +++ /dev/null @@ -1,311 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - Win32Proj - AlethZero - AlethZero - {BFCFFC46-78A3-4350-9938-0EA3A2B1CCCD} - - - - Application - true - v120 - - - Application - true - v120 - - - Application - false - v120 - - - Application - false - v120 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - false - - - false - - - - Use - Disabled - WIN32;_WINSOCK_DEPRECATED_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - true - stdafx.h - - - Windows - true - true - - - - - - - - - Use - Disabled - WIN32;_DEBUG;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - true - stdafx.h - - - Windows - true - - - - - - - - - Use - MaxSpeed - true - true - WIN32;_WINSOCK_DEPRECATED_NO_WARNINGS;NDEBUG;%(PreprocessorDefinitions) - MultiThreadedDLL - true - AnySuitable - stdafx.h - - - Windows - true - true - true - true - - - - - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;%(PreprocessorDefinitions) - MultiThreadedDLL - true - AnySuitable - stdafx.h - - - Windows - true - true - true - - - - - - - - - {df3c5b07-a1a2-4f16-b37f-a27333622cdd} - - - {f174e81a-2a66-4693-b917-11bb42d3658c} - - - - - - - - - - Create - Create - Create - Create - - - - - - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - $(IntDir)moc_%(FileName).cpp - - - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - - - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - - - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - - - $(IntDir)moc_%(FileName).cpp - $(IntDir)moc_%(FileName).cpp - $(IntDir)moc_%(FileName).cpp - - - - - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - - - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - - - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - - - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - - - $(IntDir)moc_%(FileName).cpp - $(IntDir)moc_%(FileName).cpp - $(IntDir)moc_%(FileName).cpp - $(IntDir)moc_%(FileName).cpp - - - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - - - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - - - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - - - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - - - $(IntDir)moc_%(FileName).cpp - $(IntDir)moc_%(FileName).cpp - $(IntDir)moc_%(FileName).cpp - $(IntDir)moc_%(FileName).cpp - - - - - - Document - "$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)" - "$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)" - $(IntDir)ui_%(FileName).h - "$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)" - "$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)" - $(IntDir)ui_%(FileName).h - "$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)" - "$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)" - $(IntDir)ui_%(FileName).h - "$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)" - "$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)" - $(IntDir)ui_%(FileName).h - - - - - Document - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(IntDir)%(FileName).h - $(IntDir)%(FileName).h - $(IntDir)%(FileName).h - $(IntDir)%(FileName).h - ../.git/index - ../.git/index - ../.git/index - ../.git/index - - - - - - - - - - - - - $(BuildDependsOn);FinalCopy - - - - - - - - \ No newline at end of file diff --git a/windows/Alethzero.vcxproj.filters b/windows/Alethzero.vcxproj.filters deleted file mode 100644 index ef47bdba0..000000000 --- a/windows/Alethzero.vcxproj.filters +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - Windows - - - Windows - - - - - - - - Windows - - - - - - - {049fb46c-1677-45cb-95ae-3a2d9e3090be} - - - - - - - Windows - - - - - \ No newline at end of file diff --git a/windows/BuildInfo.lua b/windows/BuildInfo.lua deleted file mode 100644 index 47b23a795..000000000 --- a/windows/BuildInfo.lua +++ /dev/null @@ -1,25 +0,0 @@ - -function os.capture(cmd) - local f = io.popen(cmd, 'r') - if (f) then - local s = f:read('*a') - if (f:close()) then - return s - end - end - return nil -end - -hash = (os.capture("git rev-parse HEAD") or "UnknownRevision"):gsub("\n$", "") -clean = ((os.capture("git diff --name-only") or "0"):gsub("\n$", "") == "") and "1" or "0" - -local output = io.open(arg[1], "w") -if (output) then - output:write("// This file was automatically generated by buildinfo.lua\n#pragma once\n\n") - output:write("#define ETH_COMMIT_HASH "..hash.."\n") - output:write("#define ETH_CLEAN_REPO "..clean.."\n") - output:close() -end - - - diff --git a/windows/Eth.vcxproj b/windows/Eth.vcxproj deleted file mode 100644 index 9b2d47727..000000000 --- a/windows/Eth.vcxproj +++ /dev/null @@ -1,195 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - Win32Proj - Ethereum - eth - {C60C065C-2135-4B2B-AFD4-35FD7AC56B40} - - - - Application - true - v120 - - - Application - true - v120 - - - Application - false - v120 - - - Application - false - v120 - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - false - - - false - - - - - - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - true - - - Console - true - true - - - - - - - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - true - - - Console - true - - - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - AnySuitable - - - Console - true - true - true - true - - - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - AnySuitable - - - Console - true - true - true - - - - - {826e68cb-d3ee-4a8a-b540-59a8c3f38d4f} - - - - - - - - Document - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(IntDir)%(FileName).h - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(IntDir)%(FileName).h - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(IntDir)%(FileName).h - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(IntDir)%(FileName).h - ../.git/index - ../.git/index - ../.git/index - ../.git/index - - - - - - - $(BuildDependsOn);FinalCopy - - - - - - - - \ No newline at end of file diff --git a/windows/Ethereum.sln b/windows/Ethereum.sln deleted file mode 100644 index 26fe794c2..000000000 --- a/windows/Ethereum.sln +++ /dev/null @@ -1,191 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Express 2013 for Windows Desktop -VisualStudioVersion = 12.0.21005.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libs", "Libs", "{988F2383-FA1D-408B-BCF6-C0EE7AB0A560}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{6838FA95-01BF-4FF7-914C-FC209B81406E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibEthereum", "LibEthereum.vcxproj", "{826E68CB-D3EE-4A8A-B540-59A8C3F38D4F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibLevelDB", "LibLevelDB.vcxproj", "{27014763-955D-486B-9BA7-69872192E6F4}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibSecp256k1", "LibSecp256k1.vcxproj", "{1E1175BB-C4A9-41D8-B2D1-9022F71D3CEA}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestSecp256k1", "TestSecp256k1.vcxproj", "{3BF049F8-AF7E-4E1C-9627-3E94C887AF24}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestEthereum", "TestEthereum.vcxproj", "{3F3E389B-88DE-41D5-A73B-4F6036E18B36}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibCryptoPP", "LibCryptoPP.vcxproj", "{1CC213A4-3482-4211-B47B-172E90DAC7DE}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibMiniUPnPc", "LibMiniUPnPc.vcxproj", "{1B1CA20E-39C3-4D9B-AC37-3783048E6672}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AlethZero", "Alethzero.vcxproj", "{BFCFFC46-78A3-4350-9938-0EA3A2B1CCCD}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibQEthereum", "LibQEthereum.vcxproj", "{DF3C5B07-A1A2-4F16-B37F-A27333622CDD}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "eth", "Eth.vcxproj", "{C60C065C-2135-4B2B-AFD4-35FD7AC56B40}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "neth", "Neth.vcxproj", "{90C70663-7181-4E99-9079-54188CEB8954}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibSerpent", "LibSerpent.vcxproj", "{F174E81A-2A66-4693-B917-11BB42D3658C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "exp", "Exp.vcxproj", "{9AA5CF66-1150-4A02-B40E-3B89740DADB8}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sc", "Sc.vcxproj", "{90068D1B-070E-4C41-88B0-1E243E1E5BFF}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lllc", "Lllc.vcxproj", "{255BDC68-B8DB-465F-8220-981E77684189}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {826E68CB-D3EE-4A8A-B540-59A8C3F38D4F}.Debug|Win32.ActiveCfg = Debug|Win32 - {826E68CB-D3EE-4A8A-B540-59A8C3F38D4F}.Debug|Win32.Build.0 = Debug|Win32 - {826E68CB-D3EE-4A8A-B540-59A8C3F38D4F}.Debug|x64.ActiveCfg = Debug|x64 - {826E68CB-D3EE-4A8A-B540-59A8C3F38D4F}.Debug|x64.Build.0 = Debug|x64 - {826E68CB-D3EE-4A8A-B540-59A8C3F38D4F}.Release|Win32.ActiveCfg = Release|Win32 - {826E68CB-D3EE-4A8A-B540-59A8C3F38D4F}.Release|Win32.Build.0 = Release|Win32 - {826E68CB-D3EE-4A8A-B540-59A8C3F38D4F}.Release|x64.ActiveCfg = Release|x64 - {826E68CB-D3EE-4A8A-B540-59A8C3F38D4F}.Release|x64.Build.0 = Release|x64 - {27014763-955D-486B-9BA7-69872192E6F4}.Debug|Win32.ActiveCfg = Debug|Win32 - {27014763-955D-486B-9BA7-69872192E6F4}.Debug|Win32.Build.0 = Debug|Win32 - {27014763-955D-486B-9BA7-69872192E6F4}.Debug|x64.ActiveCfg = Debug|x64 - {27014763-955D-486B-9BA7-69872192E6F4}.Debug|x64.Build.0 = Debug|x64 - {27014763-955D-486B-9BA7-69872192E6F4}.Release|Win32.ActiveCfg = Release|Win32 - {27014763-955D-486B-9BA7-69872192E6F4}.Release|Win32.Build.0 = Release|Win32 - {27014763-955D-486B-9BA7-69872192E6F4}.Release|x64.ActiveCfg = Release|x64 - {27014763-955D-486B-9BA7-69872192E6F4}.Release|x64.Build.0 = Release|x64 - {1E1175BB-C4A9-41D8-B2D1-9022F71D3CEA}.Debug|Win32.ActiveCfg = Debug|Win32 - {1E1175BB-C4A9-41D8-B2D1-9022F71D3CEA}.Debug|Win32.Build.0 = Debug|Win32 - {1E1175BB-C4A9-41D8-B2D1-9022F71D3CEA}.Debug|x64.ActiveCfg = Debug|x64 - {1E1175BB-C4A9-41D8-B2D1-9022F71D3CEA}.Debug|x64.Build.0 = Debug|x64 - {1E1175BB-C4A9-41D8-B2D1-9022F71D3CEA}.Release|Win32.ActiveCfg = Release|Win32 - {1E1175BB-C4A9-41D8-B2D1-9022F71D3CEA}.Release|Win32.Build.0 = Release|Win32 - {1E1175BB-C4A9-41D8-B2D1-9022F71D3CEA}.Release|x64.ActiveCfg = Release|x64 - {1E1175BB-C4A9-41D8-B2D1-9022F71D3CEA}.Release|x64.Build.0 = Release|x64 - {3BF049F8-AF7E-4E1C-9627-3E94C887AF24}.Debug|Win32.ActiveCfg = Debug|Win32 - {3BF049F8-AF7E-4E1C-9627-3E94C887AF24}.Debug|Win32.Build.0 = Debug|Win32 - {3BF049F8-AF7E-4E1C-9627-3E94C887AF24}.Debug|x64.ActiveCfg = Debug|x64 - {3BF049F8-AF7E-4E1C-9627-3E94C887AF24}.Debug|x64.Build.0 = Debug|x64 - {3BF049F8-AF7E-4E1C-9627-3E94C887AF24}.Release|Win32.ActiveCfg = Release|Win32 - {3BF049F8-AF7E-4E1C-9627-3E94C887AF24}.Release|Win32.Build.0 = Release|Win32 - {3BF049F8-AF7E-4E1C-9627-3E94C887AF24}.Release|x64.ActiveCfg = Release|x64 - {3BF049F8-AF7E-4E1C-9627-3E94C887AF24}.Release|x64.Build.0 = Release|x64 - {3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Debug|Win32.ActiveCfg = Debug|Win32 - {3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Debug|Win32.Build.0 = Debug|Win32 - {3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Debug|x64.ActiveCfg = Debug|x64 - {3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Debug|x64.Build.0 = Debug|x64 - {3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Release|Win32.ActiveCfg = Release|Win32 - {3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Release|Win32.Build.0 = Release|Win32 - {3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Release|x64.ActiveCfg = Release|x64 - {3F3E389B-88DE-41D5-A73B-4F6036E18B36}.Release|x64.Build.0 = Release|x64 - {1CC213A4-3482-4211-B47B-172E90DAC7DE}.Debug|Win32.ActiveCfg = Debug|Win32 - {1CC213A4-3482-4211-B47B-172E90DAC7DE}.Debug|Win32.Build.0 = Debug|Win32 - {1CC213A4-3482-4211-B47B-172E90DAC7DE}.Debug|x64.ActiveCfg = Debug|x64 - {1CC213A4-3482-4211-B47B-172E90DAC7DE}.Debug|x64.Build.0 = Debug|x64 - {1CC213A4-3482-4211-B47B-172E90DAC7DE}.Release|Win32.ActiveCfg = Release|Win32 - {1CC213A4-3482-4211-B47B-172E90DAC7DE}.Release|Win32.Build.0 = Release|Win32 - {1CC213A4-3482-4211-B47B-172E90DAC7DE}.Release|x64.ActiveCfg = Release|x64 - {1CC213A4-3482-4211-B47B-172E90DAC7DE}.Release|x64.Build.0 = Release|x64 - {1B1CA20E-39C3-4D9B-AC37-3783048E6672}.Debug|Win32.ActiveCfg = Debug|Win32 - {1B1CA20E-39C3-4D9B-AC37-3783048E6672}.Debug|Win32.Build.0 = Debug|Win32 - {1B1CA20E-39C3-4D9B-AC37-3783048E6672}.Debug|x64.ActiveCfg = Debug|x64 - {1B1CA20E-39C3-4D9B-AC37-3783048E6672}.Debug|x64.Build.0 = Debug|x64 - {1B1CA20E-39C3-4D9B-AC37-3783048E6672}.Release|Win32.ActiveCfg = Release|Win32 - {1B1CA20E-39C3-4D9B-AC37-3783048E6672}.Release|Win32.Build.0 = Release|Win32 - {1B1CA20E-39C3-4D9B-AC37-3783048E6672}.Release|x64.ActiveCfg = Release|x64 - {1B1CA20E-39C3-4D9B-AC37-3783048E6672}.Release|x64.Build.0 = Release|x64 - {BFCFFC46-78A3-4350-9938-0EA3A2B1CCCD}.Debug|Win32.ActiveCfg = Debug|Win32 - {BFCFFC46-78A3-4350-9938-0EA3A2B1CCCD}.Debug|Win32.Build.0 = Debug|Win32 - {BFCFFC46-78A3-4350-9938-0EA3A2B1CCCD}.Debug|x64.ActiveCfg = Debug|x64 - {BFCFFC46-78A3-4350-9938-0EA3A2B1CCCD}.Debug|x64.Build.0 = Debug|x64 - {BFCFFC46-78A3-4350-9938-0EA3A2B1CCCD}.Release|Win32.ActiveCfg = Release|Win32 - {BFCFFC46-78A3-4350-9938-0EA3A2B1CCCD}.Release|Win32.Build.0 = Release|Win32 - {BFCFFC46-78A3-4350-9938-0EA3A2B1CCCD}.Release|x64.ActiveCfg = Release|x64 - {BFCFFC46-78A3-4350-9938-0EA3A2B1CCCD}.Release|x64.Build.0 = Release|x64 - {326EF470-463F-4751-A22A-48BBAAD8B143}.Debug|Win32.ActiveCfg = Debug|Win32 - {326EF470-463F-4751-A22A-48BBAAD8B143}.Debug|Win32.Build.0 = Debug|Win32 - {326EF470-463F-4751-A22A-48BBAAD8B143}.Debug|x64.ActiveCfg = Debug|x64 - {326EF470-463F-4751-A22A-48BBAAD8B143}.Debug|x64.Build.0 = Debug|x64 - {326EF470-463F-4751-A22A-48BBAAD8B143}.Release|Win32.ActiveCfg = Release|Win32 - {326EF470-463F-4751-A22A-48BBAAD8B143}.Release|Win32.Build.0 = Release|Win32 - {326EF470-463F-4751-A22A-48BBAAD8B143}.Release|x64.ActiveCfg = Release|x64 - {326EF470-463F-4751-A22A-48BBAAD8B143}.Release|x64.Build.0 = Release|x64 - {DF3C5B07-A1A2-4F16-B37F-A27333622CDD}.Debug|Win32.ActiveCfg = Debug|Win32 - {DF3C5B07-A1A2-4F16-B37F-A27333622CDD}.Debug|Win32.Build.0 = Debug|Win32 - {DF3C5B07-A1A2-4F16-B37F-A27333622CDD}.Debug|x64.ActiveCfg = Debug|x64 - {DF3C5B07-A1A2-4F16-B37F-A27333622CDD}.Debug|x64.Build.0 = Debug|x64 - {DF3C5B07-A1A2-4F16-B37F-A27333622CDD}.Release|Win32.ActiveCfg = Release|Win32 - {DF3C5B07-A1A2-4F16-B37F-A27333622CDD}.Release|Win32.Build.0 = Release|Win32 - {DF3C5B07-A1A2-4F16-B37F-A27333622CDD}.Release|x64.ActiveCfg = Release|x64 - {DF3C5B07-A1A2-4F16-B37F-A27333622CDD}.Release|x64.Build.0 = Release|x64 - {C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Debug|Win32.ActiveCfg = Debug|Win32 - {C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Debug|Win32.Build.0 = Debug|Win32 - {C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Debug|x64.ActiveCfg = Debug|x64 - {C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Debug|x64.Build.0 = Debug|x64 - {C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Release|Win32.ActiveCfg = Release|Win32 - {C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Release|Win32.Build.0 = Release|Win32 - {C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Release|x64.ActiveCfg = Release|x64 - {C60C065C-2135-4B2B-AFD4-35FD7AC56B40}.Release|x64.Build.0 = Release|x64 - {90C70663-7181-4E99-9079-54188CEB8954}.Debug|Win32.ActiveCfg = Debug|Win32 - {90C70663-7181-4E99-9079-54188CEB8954}.Debug|Win32.Build.0 = Debug|Win32 - {90C70663-7181-4E99-9079-54188CEB8954}.Debug|x64.ActiveCfg = Debug|x64 - {90C70663-7181-4E99-9079-54188CEB8954}.Debug|x64.Build.0 = Debug|x64 - {90C70663-7181-4E99-9079-54188CEB8954}.Release|Win32.ActiveCfg = Release|Win32 - {90C70663-7181-4E99-9079-54188CEB8954}.Release|Win32.Build.0 = Release|Win32 - {90C70663-7181-4E99-9079-54188CEB8954}.Release|x64.ActiveCfg = Release|x64 - {90C70663-7181-4E99-9079-54188CEB8954}.Release|x64.Build.0 = Release|x64 - {F174E81A-2A66-4693-B917-11BB42D3658C}.Debug|Win32.ActiveCfg = Debug|Win32 - {F174E81A-2A66-4693-B917-11BB42D3658C}.Debug|Win32.Build.0 = Debug|Win32 - {F174E81A-2A66-4693-B917-11BB42D3658C}.Debug|x64.ActiveCfg = Debug|x64 - {F174E81A-2A66-4693-B917-11BB42D3658C}.Debug|x64.Build.0 = Debug|x64 - {F174E81A-2A66-4693-B917-11BB42D3658C}.Release|Win32.ActiveCfg = Release|Win32 - {F174E81A-2A66-4693-B917-11BB42D3658C}.Release|Win32.Build.0 = Release|Win32 - {F174E81A-2A66-4693-B917-11BB42D3658C}.Release|x64.ActiveCfg = Release|x64 - {F174E81A-2A66-4693-B917-11BB42D3658C}.Release|x64.Build.0 = Release|x64 - {9AA5CF66-1150-4A02-B40E-3B89740DADB8}.Debug|Win32.ActiveCfg = Debug|Win32 - {9AA5CF66-1150-4A02-B40E-3B89740DADB8}.Debug|Win32.Build.0 = Debug|Win32 - {9AA5CF66-1150-4A02-B40E-3B89740DADB8}.Debug|x64.ActiveCfg = Debug|x64 - {9AA5CF66-1150-4A02-B40E-3B89740DADB8}.Debug|x64.Build.0 = Debug|x64 - {9AA5CF66-1150-4A02-B40E-3B89740DADB8}.Release|Win32.ActiveCfg = Release|Win32 - {9AA5CF66-1150-4A02-B40E-3B89740DADB8}.Release|Win32.Build.0 = Release|Win32 - {9AA5CF66-1150-4A02-B40E-3B89740DADB8}.Release|x64.ActiveCfg = Release|x64 - {9AA5CF66-1150-4A02-B40E-3B89740DADB8}.Release|x64.Build.0 = Release|x64 - {90068D1B-070E-4C41-88B0-1E243E1E5BFF}.Debug|Win32.ActiveCfg = Debug|Win32 - {90068D1B-070E-4C41-88B0-1E243E1E5BFF}.Debug|Win32.Build.0 = Debug|Win32 - {90068D1B-070E-4C41-88B0-1E243E1E5BFF}.Debug|x64.ActiveCfg = Debug|x64 - {90068D1B-070E-4C41-88B0-1E243E1E5BFF}.Debug|x64.Build.0 = Debug|x64 - {90068D1B-070E-4C41-88B0-1E243E1E5BFF}.Release|Win32.ActiveCfg = Release|Win32 - {90068D1B-070E-4C41-88B0-1E243E1E5BFF}.Release|Win32.Build.0 = Release|Win32 - {90068D1B-070E-4C41-88B0-1E243E1E5BFF}.Release|x64.ActiveCfg = Release|x64 - {90068D1B-070E-4C41-88B0-1E243E1E5BFF}.Release|x64.Build.0 = Release|x64 - {255BDC68-B8DB-465F-8220-981E77684189}.Debug|Win32.ActiveCfg = Debug|Win32 - {255BDC68-B8DB-465F-8220-981E77684189}.Debug|Win32.Build.0 = Debug|Win32 - {255BDC68-B8DB-465F-8220-981E77684189}.Debug|x64.ActiveCfg = Debug|x64 - {255BDC68-B8DB-465F-8220-981E77684189}.Debug|x64.Build.0 = Debug|x64 - {255BDC68-B8DB-465F-8220-981E77684189}.Release|Win32.ActiveCfg = Release|Win32 - {255BDC68-B8DB-465F-8220-981E77684189}.Release|Win32.Build.0 = Release|Win32 - {255BDC68-B8DB-465F-8220-981E77684189}.Release|x64.ActiveCfg = Release|x64 - {255BDC68-B8DB-465F-8220-981E77684189}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {826E68CB-D3EE-4A8A-B540-59A8C3F38D4F} = {988F2383-FA1D-408B-BCF6-C0EE7AB0A560} - {27014763-955D-486B-9BA7-69872192E6F4} = {988F2383-FA1D-408B-BCF6-C0EE7AB0A560} - {1E1175BB-C4A9-41D8-B2D1-9022F71D3CEA} = {988F2383-FA1D-408B-BCF6-C0EE7AB0A560} - {1CC213A4-3482-4211-B47B-172E90DAC7DE} = {988F2383-FA1D-408B-BCF6-C0EE7AB0A560} - {1B1CA20E-39C3-4D9B-AC37-3783048E6672} = {988F2383-FA1D-408B-BCF6-C0EE7AB0A560} - {DF3C5B07-A1A2-4F16-B37F-A27333622CDD} = {988F2383-FA1D-408B-BCF6-C0EE7AB0A560} - {F174E81A-2A66-4693-B917-11BB42D3658C} = {988F2383-FA1D-408B-BCF6-C0EE7AB0A560} - {3BF049F8-AF7E-4E1C-9627-3E94C887AF24} = {6838FA95-01BF-4FF7-914C-FC209B81406E} - {3F3E389B-88DE-41D5-A73B-4F6036E18B36} = {6838FA95-01BF-4FF7-914C-FC209B81406E} - EndGlobalSection -EndGlobal diff --git a/windows/Ethereum.vcxproj.filters b/windows/Ethereum.vcxproj.filters deleted file mode 100644 index 0bee64924..000000000 --- a/windows/Ethereum.vcxproj.filters +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - {ed0eafbf-bbfb-4700-b7c0-9b58049cc681} - - - - - Windows - - - \ No newline at end of file diff --git a/windows/Exp.vcxproj b/windows/Exp.vcxproj deleted file mode 100644 index cf4eb5d2e..000000000 --- a/windows/Exp.vcxproj +++ /dev/null @@ -1,195 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - Win32Proj - Ethereum - exp - {9AA5CF66-1150-4A02-B40E-3B89740DADB8} - - - - Application - true - v120 - - - Application - true - v120 - - - Application - false - v120 - - - Application - false - v120 - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - false - - - false - - - - - - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - true - - - Console - true - true - - - - - - - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - true - - - Console - true - - - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - AnySuitable - - - Console - true - true - true - true - - - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - AnySuitable - - - Console - true - true - true - - - - - {826e68cb-d3ee-4a8a-b540-59a8c3f38d4f} - - - - - Document - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(IntDir)%(FileName).h - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(IntDir)%(FileName).h - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(IntDir)%(FileName).h - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(IntDir)%(FileName).h - ../.git/index - ../.git/index - ../.git/index - ../.git/index - - - - - - - - - - $(BuildDependsOn);FinalCopy - - - - - - - - \ No newline at end of file diff --git a/windows/LibCryptoPP.vcxproj b/windows/LibCryptoPP.vcxproj deleted file mode 100644 index 032ae5fa6..000000000 --- a/windows/LibCryptoPP.vcxproj +++ /dev/null @@ -1,414 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Document - ml64.exe /c /nologo /Fo"$(IntDir)x64dll.obj" /Zi "%(FullPath)" - ml64.exe /c /nologo /Fo"$(IntDir)x64dll.obj" /Zi "%(FullPath)" - $(IntDir)x64dll.obj - $(IntDir)x64dll.obj - - - - Win32Proj - LibCryptoPP - {1CC213A4-3482-4211-B47B-172E90DAC7DE} - - - - StaticLibrary - true - v120 - - - StaticLibrary - true - v120 - - - StaticLibrary - false - v120 - - - StaticLibrary - false - v120 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Disabled - MultiThreadedDebugDLL - 4100;4189;4244;%(DisableSpecificWarnings) - - - Windows - true - - - - - - - Disabled - MultiThreadedDebugDLL - 4100;4189;4244;%(DisableSpecificWarnings) - - - Windows - true - - - - - - - MaxSpeed - true - true - MultiThreadedDLL - 4100;4189;4244;%(DisableSpecificWarnings) - - - Windows - true - true - true - - - - - - - MaxSpeed - true - true - MultiThreadedDLL - 4100;4189;4244;%(DisableSpecificWarnings) - - - Windows - true - true - true - - - - - - \ No newline at end of file diff --git a/windows/LibEthereum.props b/windows/LibEthereum.props deleted file mode 100644 index 8c0bcac90..000000000 --- a/windows/LibEthereum.props +++ /dev/null @@ -1,35 +0,0 @@ - - - - - ../../boost - "../../lua/lua" - - - ..\..\_build\$(ProjectName)\$(Platform)_$(Configuration)\ - ..\..\_build\$(ProjectName)\$(Platform)_$(Configuration)\ - - - - 4068;4244;4267 - true - false - include/$(ProjectName);$(IntDir);../../cryptopp;..;../libethcore;../libethereum;../libethsupport;$(BoostDir);../../leveldb/include;../secp256k1;../../miniupnp - ETH_BUILD_PLATFORM=Windows/VS2013;ETH_BUILD_TYPE=$(Configuration)-$(Platform);ETH_MINIUPNPC=1;STATICLIB;LEVELDB_PLATFORM_WINDOWS;USE_NUM_BOOST;USE_FIELD_10X26;USE_FIELD_INV_BUILTIN;_WIN32_WINNT=0x0501;WIN32;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - true - Level3 - - - $(BoostDir)/stage/$(Platform) - - - - - $(BoostDir) - - - $(Lua) - - - \ No newline at end of file diff --git a/windows/LibEthereum.vcxproj b/windows/LibEthereum.vcxproj deleted file mode 100644 index 06f868023..000000000 --- a/windows/LibEthereum.vcxproj +++ /dev/null @@ -1,571 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - - - - - - - - - - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - - - - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - - - true - true - true - true - - - - stdafx.h - Create - Create - Create - Create - - - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - - - - - - - - - - - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - - - - - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - true - true - true - true - - - - true - true - true - true - - - true - true - true - true - - - - - - {1cc213a4-3482-4211-b47b-172e90dac7de} - - - {27014763-955d-486b-9ba7-69872192e6f4} - - - {1b1ca20e-39c3-4d9b-ac37-3783048e6672} - - - {1e1175bb-c4a9-41d8-b2d1-9022f71d3cea} - - - - {826E68CB-D3EE-4A8A-B540-59A8C3F38D4F} - Win32Proj - LibEthereum - - - - StaticLibrary - true - v120 - - - StaticLibrary - true - v120 - - - StaticLibrary - false - v120 - - - StaticLibrary - false - v120 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - false - MultiThreadedDebugDLL - Use - stdafx.h - - - Windows - true - - - - - Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - false - MultiThreadedDebugDLL - stdafx.h - Use - - - Windows - true - - - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - Use - stdafx.h - - - Windows - true - true - true - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - Use - stdafx.h - - - Windows - true - true - true - - - - - - diff --git a/windows/LibEthereum.vcxproj.filters b/windows/LibEthereum.vcxproj.filters deleted file mode 100644 index 114364008..000000000 --- a/windows/LibEthereum.vcxproj.filters +++ /dev/null @@ -1,477 +0,0 @@ - - - - - Windows - - - libethereum - - - libethereum - - - libethereum - - - libethereum - - - libethereum - - - libethereum - - - libethereum - - - libethereum - - - libevm - - - libevm - - - libevm - - - libevmcore - - - liblll - - - liblll - - - liblll - - - liblll - - - libethereum - - - libethereum - - - libethereum - - - libethereum - - - libethereum - - - libethereum - - - libethereum - - - libdevcrypto - - - libdevcrypto - - - libdevcrypto - - - libdevcrypto - - - libdevcrypto - - - libdevcrypto - - - libdevcrypto - - - libethcore - - - libethcore - - - libethcore - - - libdevcore - - - libdevcore - - - libdevcore - - - libdevcore - - - libdevcore - - - libdevcore - - - libdevcore - - - libethcore - - - libevm - - - libethereum - - - libethereum - - - libethereum - - - libethereum - - - libethereum - - - libp2p - - - libp2p - - - libp2p - - - libp2p - - - libp2p - - - libp2p - - - libwhisper - - - libwhisper - - - libethereum - - - libdevcore - - - libdevcore - - - libethereum - - - libwebthree - - - libethcore - - - libdevcrypto - - - libdevcrypto - - - libdevcrypto - - - libethereum - - - libevmcore - - - - - Windows - - - libethereum - - - libethereum - - - libethereum - - - libethereum - - - libethereum - - - libethereum - - - libethereum - - - libethereum - - - libevm - - - libevm - - - libevm - - - libevm - - - libevmcore - - - liblll - - - liblll - - - liblll - - - liblll - - - liblll - - - liblll - - - libethereum - - - libethereum - - - libethereum - - - libethereum - - - libethereum - - - libethereum - - - libethereum - - - libdevcrypto - - - libdevcrypto - - - libdevcrypto - - - libdevcrypto - - - libdevcrypto - - - libdevcrypto - - - libdevcrypto - - - libdevcrypto - - - libdevcrypto - - - libethcore - - - libethcore - - - libethcore - - - libethcore - - - libethcore - - - libethcore - - - libdevcore - - - libdevcore - - - libdevcore - - - libdevcore - - - libdevcore - - - libdevcore - - - libdevcore - - - libdevcore - - - libdevcore - - - libdevcore - - - libethereum - - - libethereum - - - libethereum - - - libethereum - - - libethereum - - - libethereum - - - libp2p - - - libp2p - - - libp2p - - - libp2p - - - libp2p - - - libp2p - - - libp2p - - - libwhisper - - - libwhisper - - - libethereum - - - libdevcore - - - libdevcore - - - libethereum - - - libwebthree - - - libdevcrypto - - - libdevcrypto - - - libdevcrypto - - - libethereum - - - libevmcore - - - libevmcore - - - - - {2d571d8f-bacf-4c49-a0d0-c9036f5c0cc9} - - - {8275e3be-c870-44a2-8185-5a9992af8f8e} - - - {b246b3d7-af02-4125-a254-2b377214c288} - - - {37c37803-1515-47c1-b7e6-3879f4429ab3} - - - {ed9ad1b3-700c-47f9-8548-a90b5ef179ac} - - - {e6332606-e0ca-48aa-8a6b-303971ba7a93} - - - {fae2102b-d574-40fc-9f90-1b9ed0d117ac} - - - {35c32f6c-3f19-4603-8084-1b88ec9ae498} - - - {fc2cb618-ab0c-45b6-8eb9-6d88e0336fa9} - - - {36748e80-c977-4fee-84e6-699c039dff87} - - - {d838fece-fc20-42f6-bff5-97c236159b80} - - - \ No newline at end of file diff --git a/windows/LibEthereum_Debug.props b/windows/LibEthereum_Debug.props deleted file mode 100644 index 6d322078a..000000000 --- a/windows/LibEthereum_Debug.props +++ /dev/null @@ -1,18 +0,0 @@ - - - - - d - d - - - - - - $(DebugSuffix) - - - $(d) - - - \ No newline at end of file diff --git a/windows/LibEthereum_Release.props b/windows/LibEthereum_Release.props deleted file mode 100644 index 8f0436f61..000000000 --- a/windows/LibEthereum_Release.props +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - $(DebugSuffix) - - - \ No newline at end of file diff --git a/windows/LibLevelDB.vcxproj b/windows/LibLevelDB.vcxproj deleted file mode 100644 index 3e2407da6..000000000 --- a/windows/LibLevelDB.vcxproj +++ /dev/null @@ -1,221 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {27014763-955D-486B-9BA7-69872192E6F4} - Win32Proj - LibLevelDB - - - - StaticLibrary - true - v120 - - - StaticLibrary - true - v120 - - - StaticLibrary - false - v120 - - - StaticLibrary - false - v120 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Disabled - MultiThreadedDebugDLL - %(AdditionalIncludeDirectories);../../leveldb - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - 4018;4100;4244;4267;4389;4702;4722;4800;4996;%(DisableSpecificWarnings) - - - Windows - true - - - - - - - Disabled - MultiThreadedDebugDLL - %(AdditionalIncludeDirectories);../../leveldb - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - 4018;4100;4244;4267;4389;4702;4722;4800;4996;%(DisableSpecificWarnings) - - - Windows - true - - - - - - - MaxSpeed - true - true - MultiThreadedDLL - %(AdditionalIncludeDirectories);../../leveldb - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - 4018;4100;4244;4267;4389;4702;4722;4800;4996;%(DisableSpecificWarnings) - - - Windows - true - true - true - - - - - - - MaxSpeed - true - true - MultiThreadedDLL - %(AdditionalIncludeDirectories);../../leveldb - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - 4018;4100;4244;4267;4389;4702;4722;4800;4996;%(DisableSpecificWarnings) - - - Windows - true - true - true - - - - - - \ No newline at end of file diff --git a/windows/LibLevelDB.vcxproj.filters b/windows/LibLevelDB.vcxproj.filters deleted file mode 100644 index bc3306f56..000000000 --- a/windows/LibLevelDB.vcxproj.filters +++ /dev/null @@ -1,246 +0,0 @@ - - - - - {d83904b1-b5d1-4c5b-b476-96f08300d103} - - - {72573022-b7fd-4b7a-a92e-a68c06bd6366} - - - {7f821e9e-4ebf-4d18-8fb4-898bd3d81376} - - - {f285a595-6c39-4350-8d30-6f696a3a7c4c} - - - - - db - - - db - - - db - - - db - - - db - - - db - - - db - - - db - - - db - - - db - - - db - - - db - - - db - - - db - - - db - - - table - - - table - - - table - - - table - - - table - - - table - - - util - - - util - - - util - - - util - - - util - - - util - - - util - - - util - - - util - - - util - - - util - - - util - - - port - - - port - - - port - - - - - db - - - db - - - db - - - db - - - db - - - db - - - db - - - db - - - db - - - db - - - db - - - db - - - db - - - db - - - db - - - table - - - table - - - table - - - table - - - table - - - table - - - table - - - table - - - util - - - util - - - util - - - util - - - util - - - util - - - util - - - util - - - util - - - util - - - util - - - util - - - util - - - util - - - util - - - port - - - \ No newline at end of file diff --git a/windows/LibMiniUPnPc.vcxproj b/windows/LibMiniUPnPc.vcxproj deleted file mode 100644 index 07489d0e8..000000000 --- a/windows/LibMiniUPnPc.vcxproj +++ /dev/null @@ -1,182 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Win32Proj - LibMiniUPnPc - {1B1CA20E-39C3-4D9B-AC37-3783048E6672} - LibMiniUPnPc - - - - StaticLibrary - true - v120 - - - StaticLibrary - true - v120 - - - StaticLibrary - false - v120 - - - StaticLibrary - false - v120 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Disabled - MultiThreadedDebugDLL - _CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;MINIUPNP_STATICLIB;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions) - 4100;4244;4245;4267;4389;%(DisableSpecificWarnings) - - - Windows - true - - - Iphlpapi.lib - - - - - - - Disabled - MultiThreadedDebugDLL - _CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;MINIUPNP_STATICLIB;%(PreprocessorDefinitions) - 4100;4244;4245;4267;4389;%(DisableSpecificWarnings) - - - Windows - true - - - Iphlpapi.lib - - - - - - - MaxSpeed - true - true - MultiThreadedDLL - _CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;MINIUPNP_STATICLIB;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions) - 4100;4244;4245;4267;4389;%(DisableSpecificWarnings) - - - Windows - true - true - true - - - Iphlpapi.lib - - - - - - - MaxSpeed - true - true - MultiThreadedDLL - _CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;MINIUPNP_STATICLIB;%(PreprocessorDefinitions) - 4100;4244;4245;4267;4389;%(DisableSpecificWarnings) - - - Windows - true - true - true - - - Iphlpapi.lib - - - - - - \ No newline at end of file diff --git a/windows/LibQEthereum.props b/windows/LibQEthereum.props deleted file mode 100644 index 08ba05c69..000000000 --- a/windows/LibQEthereum.props +++ /dev/null @@ -1,70 +0,0 @@ - - - - - ../../Qt/$(Platform) - $(QtDir)/qtbase - $(QtBase)/bin - $(QtBase)/include;../../Qt/Src/qtbase/include;../../Qt/Src/qtbase/include/QtCore;../../Qt/Src/qtbase/include/QtWidgets;../../Qt/Src/qtbase/include/QtQml;../../Qt/Src/qtbase/include/QtGui;../../Qt/Src/qtdeclarative/include;../../Qt/Src/qtwebkit/include - $(QtBase)/lib;$(QtBase)/plugins/platforms;../../icu/lib64 - ..\..\icu\bin_$(Platform)\icu*52.dll;$(QtBase)\lib\Qt5Core$(d).dll;$(QtBase)\lib\Qt5Gui$(d).dll;$(QtBase)\lib\Qt5Multimedia$(d).dll;$(QtBase)\lib\Qt5MultimediaWidgets$(d).dll;$(QtBase)\lib\Qt5OpenGL$(d).dll;$(QtBase)\lib\Qt5Positioning$(d).dll;$(QtBase)\lib\Qt5PrintSupport$(d).dll;$(QtBase)\lib\Qt5Network$(d).dll;$(QtBase)\lib\Qt5Qml$(d).dll;$(QtBase)\lib\Qt5Quick$(d).dll;$(QtBase)\lib\Qt5Sensors$(d).dll;$(QtBase)\lib\Qt5Sql$(d).dll;$(QtBase)\lib\Qt5Webkit$(d).dll;$(QtBase)\lib\Qt5WebkitWidgets$(d).dll;$(QtBase)\lib\Qt5Widgets$(d).dll;$(QtBase)\plugins\**\qwindows$(d).dll;$(QtBase)\plugins\**\qgenericbearer$(d).dll;$(QtBase)\plugins\**\qnativewifibearer$(d).dll;$(QtBase)\plugins\**\qgif$(d).dll;$(QtBase)\plugins\**\qico$(d).dll;$(QtBase)\plugins\**\qjpeg$(d).dll;$(QtBase)\plugins\**\qsvg$(d).dll;$(QtBase)\plugins\**\qtsensors_dummy$(d).dll - - - <_PropertySheetDisplayName>LibQEthereum - - - - - ..;$(QtInclude);%(AdditionalIncludeDirectories) - 4718;%(DisableSpecificWarnings) - ETH_QTQML=1;%(PreprocessorDefinitions) - - - - - - - - - $(QtLib);%(AdditionalLibraryDirectories) - Qt5PlatformSupport$(d).lib;Qt5Core$(d).lib;Qt5GUI$(d).lib;Qt5Network$(d).lib;Qt5Quick$(d).lib;Qt5Qml$(d).lib;Qt5Webkit$(d).lib;Qt5WebkitWidgets$(d).lib;Qt5Widgets$(d).lib;%(AdditionalDependencies) - - - - - $(QtDir) - - - $(QtBase) - - - $(QtBin) - - - $(QtInclude) - - - $(QtLib) - - - $(CopyDlls) - - - - - - - - - - \ No newline at end of file diff --git a/windows/LibQEthereum.vcxproj b/windows/LibQEthereum.vcxproj deleted file mode 100644 index 20b29e06e..000000000 --- a/windows/LibQEthereum.vcxproj +++ /dev/null @@ -1,204 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - {826e68cb-d3ee-4a8a-b540-59a8c3f38d4f} - - - - - - - Create - Create - Create - Create - - - - - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - - - $(IntDir)moc_%(FileName).cpp - - - $(IntDir)moc_%(FileName).cpp - - - $(IntDir)moc_%(FileName).cpp - - - $(IntDir)moc_%(FileName).cpp - - - - - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - - - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - - - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - - - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - - - $(IntDir)moc_%(FileName).cpp - $(IntDir)moc_%(FileName).cpp - $(IntDir)moc_%(FileName).cpp - $(IntDir)moc_%(FileName).cpp - - - - - Win32Proj - LibQEthereum - {DF3C5B07-A1A2-4F16-B37F-A27333622CDD} - - - - StaticLibrary - true - v120 - - - StaticLibrary - true - v120 - - - StaticLibrary - false - v120 - - - StaticLibrary - false - v120 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - false - MultiThreadedDebugDLL - Use - stdafx.h - - - Windows - true - - - - - Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - false - MultiThreadedDebugDLL - stdafx.h - Use - - - Windows - true - - - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - Use - stdafx.h - - - Windows - true - true - true - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - Use - stdafx.h - - - Windows - true - true - true - - - - - - \ No newline at end of file diff --git a/windows/LibQEthereum.vcxproj.filters b/windows/LibQEthereum.vcxproj.filters deleted file mode 100644 index e38730504..000000000 --- a/windows/LibQEthereum.vcxproj.filters +++ /dev/null @@ -1,24 +0,0 @@ - - - - - {516a3655-70df-49f7-af1f-008cf4acf934} - - - - - Windows - - - - - - - Windows - - - - - - - \ No newline at end of file diff --git a/windows/LibSecp256k1.vcxproj b/windows/LibSecp256k1.vcxproj deleted file mode 100644 index 37df3b3b6..000000000 --- a/windows/LibSecp256k1.vcxproj +++ /dev/null @@ -1,183 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - - - - - Win32Proj - LibSecp256k1 - {1E1175BB-C4A9-41D8-B2D1-9022F71D3CEA} - LibSecp256k1 - - - - StaticLibrary - true - v120 - - - StaticLibrary - true - v120 - - - StaticLibrary - false - v120 - - - StaticLibrary - false - v120 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - 4189;4244;4267;%(DisableSpecificWarnings) - - - Windows - true - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - 4189;4244;4267;%(DisableSpecificWarnings) - - - Windows - true - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreadedDLL - 4189;4244;4267;%(DisableSpecificWarnings) - - - Windows - true - true - true - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreadedDLL - 4189;4244;4267;%(DisableSpecificWarnings) - - - Windows - true - true - true - - - - - - \ No newline at end of file diff --git a/windows/LibSecp256k1.vcxproj.filters b/windows/LibSecp256k1.vcxproj.filters deleted file mode 100644 index aa4e5b9cb..000000000 --- a/windows/LibSecp256k1.vcxproj.filters +++ /dev/null @@ -1,71 +0,0 @@ - - - - - {7d4db365-bce7-45c1-861c-f5f86beca992} - - - - - impl - - - impl - - - impl - - - impl - - - impl - - - impl - - - impl - - - impl - - - impl - - - impl - - - impl - - - impl - - - impl - - - impl - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/windows/LibSerpent.vcxproj b/windows/LibSerpent.vcxproj deleted file mode 100644 index 925d4915b..000000000 --- a/windows/LibSerpent.vcxproj +++ /dev/null @@ -1,187 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - {1cc213a4-3482-4211-b47b-172e90dac7de} - - - {27014763-955d-486b-9ba7-69872192e6f4} - - - {1b1ca20e-39c3-4d9b-ac37-3783048e6672} - - - {1e1175bb-c4a9-41d8-b2d1-9022f71d3cea} - - - - - - - - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - Win32Proj - LibSerpent - {F174E81A-2A66-4693-B917-11BB42D3658C} - - - - StaticLibrary - true - v120 - - - StaticLibrary - true - v120 - - - StaticLibrary - false - v120 - - - StaticLibrary - false - v120 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - false - MultiThreadedDebugDLL - Use - stdafx.h - - - Windows - true - - - - - Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - false - MultiThreadedDebugDLL - stdafx.h - Use - - - Windows - true - - - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - Use - stdafx.h - - - Windows - true - true - true - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - Use - stdafx.h - - - Windows - true - true - true - - - - - - \ No newline at end of file diff --git a/windows/LibSerpent.vcxproj.filters b/windows/LibSerpent.vcxproj.filters deleted file mode 100644 index 65df02da3..000000000 --- a/windows/LibSerpent.vcxproj.filters +++ /dev/null @@ -1,18 +0,0 @@ - - - - - {20ea55ad-2a66-41df-a64e-9fed221f544f} - - - - - Windows - - - - - Windows - - - \ No newline at end of file diff --git a/windows/Lllc.vcxproj b/windows/Lllc.vcxproj deleted file mode 100644 index 70306d656..000000000 --- a/windows/Lllc.vcxproj +++ /dev/null @@ -1,195 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - Win32Proj - Ethereum - lllc - {255BDC68-B8DB-465F-8220-981E77684189} - - - - Application - true - v120 - - - Application - true - v120 - - - Application - false - v120 - - - Application - false - v120 - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - false - - - false - - - - - - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - true - - - Console - true - true - - - - - - - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - true - - - Console - true - - - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - AnySuitable - - - Console - true - true - true - true - - - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - AnySuitable - - - Console - true - true - true - - - - - {826e68cb-d3ee-4a8a-b540-59a8c3f38d4f} - - - - - Document - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(IntDir)%(FileName).h - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(IntDir)%(FileName).h - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(IntDir)%(FileName).h - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(IntDir)%(FileName).h - ../.git/index - ../.git/index - ../.git/index - ../.git/index - - - - - - - - - - $(BuildDependsOn);FinalCopy - - - - - - - - \ No newline at end of file diff --git a/windows/Neth.vcxproj b/windows/Neth.vcxproj deleted file mode 100644 index a778b78d8..000000000 --- a/windows/Neth.vcxproj +++ /dev/null @@ -1,213 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - Win32Proj - Nethereum - neth - {90C70663-7181-4E99-9079-54188CEB8954} - - - - Application - true - v120 - - - Application - true - v120 - - - Application - false - v120 - - - Application - false - v120 - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - false - - - false - - - - - - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - true - ncurses/include;ncurses/include/ncurses;%(AdditionalIncludeDirectories) - - - Console - true - true - $(BoostDir)/stage/$(Platform);ncurses/lib/$(Platform) - wncurses.lib;wform.lib;wmenu.lib;wpanel.lib;%(AdditionalDependencies) - - - - - - - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - true - ncurses/include;ncurses/include/ncurses;ncurses/include/ncurses;%(AdditionalIncludeDirectories) - - - Console - true - $(BoostDir)/stage/$(Platform);ncurses/lib/$(Platform) - wncurses.lib;wform.lib;wmenu.lib;wpanel.lib;%(AdditionalDependencies) - - - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - AnySuitable - ncurses/include;ncurses/include/ncurses;%(AdditionalIncludeDirectories) - - - Console - true - true - true - true - $(BoostDir)/stage/$(Platform);ncurses/lib/$(Platform) - wncurses.lib;wform.lib;wmenu.lib;wpanel.lib;%(AdditionalDependencies) - - - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - AnySuitable - ncurses/include;ncurses/include/ncurses;%(AdditionalIncludeDirectories) - - - Console - true - true - true - $(BoostDir)/stage/$(Platform);ncurses/lib/$(Platform) - wncurses.lib;wform.lib;wmenu.lib;wpanel.lib;%(AdditionalDependencies) - - - - - {826e68cb-d3ee-4a8a-b540-59a8c3f38d4f} - - - - - Document - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(IntDir)%(FileName).h - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(IntDir)%(FileName).h - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(IntDir)%(FileName).h - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(IntDir)%(FileName).h - ../.git/index - ../.git/index - ../.git/index - ../.git/index - - - - - - - - - - $(BuildDependsOn);FinalCopy - - - - - - - - - - - - - - \ No newline at end of file diff --git a/windows/Sc.vcxproj b/windows/Sc.vcxproj deleted file mode 100644 index 8dc0e1dee..000000000 --- a/windows/Sc.vcxproj +++ /dev/null @@ -1,198 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - Win32Proj - Ethereum - sc - {90068D1B-070E-4C41-88B0-1E243E1E5BFF} - - - - Application - true - v120 - - - Application - true - v120 - - - Application - false - v120 - - - Application - false - v120 - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - false - - - false - - - - - - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - true - - - Console - true - true - - - - - - - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - true - - - Console - true - - - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - AnySuitable - - - Console - true - true - true - true - - - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - AnySuitable - - - Console - true - true - true - - - - - {826e68cb-d3ee-4a8a-b540-59a8c3f38d4f} - - - {f174e81a-2a66-4693-b917-11bb42d3658c} - - - - - Document - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(IntDir)%(FileName).h - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(IntDir)%(FileName).h - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(IntDir)%(FileName).h - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(IntDir)%(FileName).h - ../.git/index - ../.git/index - ../.git/index - ../.git/index - - - - - - - - - - $(BuildDependsOn);FinalCopy - - - - - - - - \ No newline at end of file diff --git a/windows/TestEthereum.vcxproj b/windows/TestEthereum.vcxproj deleted file mode 100644 index 172e6be86..000000000 --- a/windows/TestEthereum.vcxproj +++ /dev/null @@ -1,194 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - Win32Proj - TestEthereum - TestEthereum - {3F3E389B-88DE-41D5-A73B-4F6036E18B36} - - - - Application - true - v120 - - - Application - true - v120 - - - Application - false - v120 - - - Application - false - v120 - - - - - - - - - - - - - - - - - - - - - - - true - - - true - - - false - - - false - - - - Use - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - true - true - stdafx.h - Async - - - Console - true - true - - - - - Use - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - true - stdafx.h - Async - - - Console - true - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - AnySuitable - true - stdafx.h - Async - - - Console - true - true - true - true - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - AnySuitable - true - stdafx.h - Async - - - Console - true - true - true - - - - - {826e68cb-d3ee-4a8a-b540-59a8c3f38d4f} - - - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - - - - - - - - \ No newline at end of file diff --git a/windows/TestEthereum.vcxproj.filters b/windows/TestEthereum.vcxproj.filters deleted file mode 100644 index 4be707aec..000000000 --- a/windows/TestEthereum.vcxproj.filters +++ /dev/null @@ -1,38 +0,0 @@ - - - - - Windows - - - - - - - - - - - - - - - - - - - - - {0acd7e2f-2594-4c13-94cb-3247045bdbfd} - - - - - Windows - - - - - - - \ No newline at end of file diff --git a/windows/TestSecp256k1.vcxproj b/windows/TestSecp256k1.vcxproj deleted file mode 100644 index d2c113d4c..000000000 --- a/windows/TestSecp256k1.vcxproj +++ /dev/null @@ -1,171 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - - - - - {1e1175bb-c4a9-41d8-b2d1-9022f71d3cea} - - - - Win32Proj - TestSecp256k1 - TestSecp256k1 - {3BF049F8-AF7E-4E1C-9627-3E94C887AF24} - - - - Application - true - v120 - - - Application - true - v120 - - - Application - false - v120 - - - Application - false - v120 - - - - - - - - - - - - - - - - - - - - - - - true - - - true - - - false - - - false - - - - - - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - true - true - 4189;4244;4267;%(DisableSpecificWarnings) - - - Console - true - true - - - - - - - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - true - 4189;4244;4267;%(DisableSpecificWarnings) - - - Console - true - - - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - AnySuitable - true - 4189;4244;4267;%(DisableSpecificWarnings) - - - Console - true - true - true - true - - - - - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - AnySuitable - true - 4189;4244;4267;%(DisableSpecificWarnings) - - - Console - true - true - true - - - - - - \ No newline at end of file diff --git a/windows/Walleth.vcxproj b/windows/Walleth.vcxproj deleted file mode 100644 index ad76f0f01..000000000 --- a/windows/Walleth.vcxproj +++ /dev/null @@ -1,315 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - Win32Proj - Walleth - Walleth - {326EF470-463F-4751-A22A-48BBAAD8B143} - - - - Application - true - v120 - - - Application - true - v120 - - - Application - false - v120 - - - Application - false - v120 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - false - - - false - - - - Use - Disabled - WIN32;_DEBUG;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - true - stdafx.h - - - Windows - true - true - - - - - - - - - - - - - - - Use - Disabled - WIN32;_DEBUG;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - true - stdafx.h - - - Windows - true - - - - - - - - - - - - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;%(PreprocessorDefinitions) - MultiThreadedDLL - true - AnySuitable - stdafx.h - - - Windows - true - true - true - true - - - - - - - - - - - - - - - Use - MaxSpeed - true - true - WIN32;NDEBUG;%(PreprocessorDefinitions) - MultiThreadedDLL - true - AnySuitable - stdafx.h - - - Windows - true - true - true - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - $(IntDir)moc_%(FileName).cpp - - - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - - - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - - - $(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)" - - - $(IntDir)moc_%(FileName).cpp - $(IntDir)moc_%(FileName).cpp - $(IntDir)moc_%(FileName).cpp - - - - - - Document - "$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)" - "$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)" - $(IntDir)ui_%(FileName).h - "$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)" - "$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)" - $(IntDir)ui_%(FileName).h - "$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)" - "$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)" - $(IntDir)ui_%(FileName).h - "$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)" - "$(QtBin)/uic" -o "$(IntDir)ui_%(FileName).h" "%(FullPath)" - $(IntDir)ui_%(FileName).h - - - - - Document - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(Lua) "%(FullPath)" "$(IntDir)%(FileName).h" - - - $(IntDir)%(FileName).h - $(IntDir)%(FileName).h - $(IntDir)%(FileName).h - $(IntDir)%(FileName).h - ../.git/index - ../.git/index - ../.git/index - ../.git/index - - - - - {df3c5b07-a1a2-4f16-b37f-a27333622cdd} - - - - - Document - "$(QtBin)/rcc" -o "$(IntDir)qrc_%(FileName).cpp" "%(FullPath)" - "$(QtBin)/rcc" -o "$(IntDir)qrc_%(FileName).cpp" "%(FullPath)" - "$(QtBin)/rcc" -o "$(IntDir)qrc_%(FileName).cpp" "%(FullPath)" - "$(QtBin)/rcc" -o "$(IntDir)qrc_%(FileName).cpp" "%(FullPath)" - "$(QtBin)/rcc" -o "$(IntDir)qrc_%(FileName).cpp" "%(FullPath)" - "$(QtBin)/rcc" -o "$(IntDir)qrc_%(FileName).cpp" "%(FullPath)" - "$(QtBin)/rcc" -o "$(IntDir)qrc_%(FileName).cpp" "%(FullPath)" - "$(QtBin)/rcc" -o "$(IntDir)qrc_%(FileName).cpp" "%(FullPath)" - $(IntDir)qrc_%(FileName).cpp - $(IntDir)qrc_%(FileName).cpp - $(IntDir)qrc_%(FileName).cpp - $(IntDir)qrc_%(FileName).cpp - ../Walleth/Simple.qml - ../Walleth/Simple.qml - ../Walleth/Simple.qml - ../Walleth/Simple.qml - - - - - - - - - - - - - - $(BuildDependsOn);FinalCopy - - - - - - - - \ No newline at end of file diff --git a/windows/Walleth.vcxproj.filters b/windows/Walleth.vcxproj.filters deleted file mode 100644 index 804248d9f..000000000 --- a/windows/Walleth.vcxproj.filters +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - Windows - - - Windows - - - - - - - Windows - - - - - - {37f5b48c-b602-474b-8683-041898e328b5} - - - - - Windows - - - - - - \ No newline at end of file diff --git a/windows/WinMain.cpp b/windows/WinMain.cpp deleted file mode 100644 index d2fc147ca..000000000 --- a/windows/WinMain.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// http://www.flipcode.com/archives/WinMain_Command_Line_Parser.shtml -// COTD Entry submitted by Max McGuire [amcguire@andrew.cmu.edu] - -#include - -extern int main(int argc, char* argv[]); - -int WINAPI WinMain(HINSTANCE /*instance*/, HINSTANCE /*prev_instance*/, char* command_line, int /*show_command*/) -{ - int argc; - char** argv; - char* arg; - int index; - int result; - - // count the arguments - argc = 1; - arg = command_line; - - while (arg[0] != 0) - { - while (arg[0] != 0 && arg[0] == ' ') - { - arg++; - } - if (arg[0] != 0) - { - argc++; - while (arg[0] != 0 && arg[0] != ' ') - { - arg++; - } - } - } - - // tokenize the arguments - argv = (char**)malloc(argc * sizeof(char*)); - arg = command_line; - index = 1; - - while (arg[0] != 0) - { - while (arg[0] != 0 && arg[0] == ' ') - { - arg++; - } - if (arg[0] != 0) - { - argv[index] = arg; - index++; - while (arg[0] != 0 && arg[0] != ' ') - { - arg++; - } - if (arg[0] != 0) - { - arg[0] = 0; - arg++; - } - } - } - - // put the program name into argv[0] - char filename[_MAX_PATH]; - GetModuleFileName(NULL, filename, _MAX_PATH); - argv[0] = filename; - - // call the user specified main function - result = main(argc, argv); - free(argv); - return result; -} diff --git a/windows/bootstrap.sh b/windows/bootstrap.sh deleted file mode 100644 index 642c3f5c8..000000000 --- a/windows/bootstrap.sh +++ /dev/null @@ -1,233 +0,0 @@ -#!/bin/bash -# @file bootstrap.sh -# @author Tim Hughes -# @date 2014 -# Script to fetch and compile depdencies for building Ethereum using Visual Studio Express 2013. -# Prerequisites: -# - Visual Studio Express 2013 for Desktop -# - On PATH: bash, git, git-svn, curl, 7z, perl, ruby, python - -error_exit() -{ - echo $1 1>&2 - exit 1 -} - -# check for existance of basic tools -for i in gawk sed curl git 7z; do - which $i &>/dev/null || error_exit "Could not find $i on PATH" -done - -# get commands before they are removed from the path -sed=`which sed` -awk=`which gawk` -which=`which which` - -path_remove() -{ - export PATH=`echo -n $PATH | "$awk" -v RS=: -v ORS=: '$0 != "'$1'"' | "$sed" 's/:$//'` -} - -path_remove_bin() -{ - path_remove "/bin" - path_remove "/usr/bin" - path_remove "/usr/local/bin" -} - -# check for native perl, python and ruby installations (needed by Qt) -( - path_remove_bin; - for i in ruby python perl; do - "$which" $i &>/dev/null || error_exit "Could not find $i on PATH" - done -) - -if [ ! -d "$VS120COMNTOOLS" ]; then - error_exit "Couldn't find Visual Studio 2013" -fi - -if [[ ! $@ ]] || [ $1 == "fetch" ]; then - # fetch ethereum (develop branch) - if [ ! -d cpp-ethereum ]; then - (set -x; git clone https://github.com/ethereum/cpp-ethereum.git) - cd cpp-ethereum - (set -x; git checkout -b develop origin/develop) - cd .. - echo - fi - - # fetch CryptoPP-5.6.2 - if [ ! -d cryptopp ]; then - (set -x; git svn clone -r 541:541 http://svn.code.sf.net/p/cryptopp/code/trunk/c5 cryptopp) - echo - fi - - # fetch MiniUPnP-1.8 - if [ ! -d miniupnp ]; then - (set -x; git clone https://github.com/miniupnp/miniupnp.git) - cd miniupnp - (set -x; git checkout tags/miniupnpd_1_8) - cd .. - echo - fi - - # fetch LevelDB (windows branch) - if [ ! -d leveldb ]; then - (set -x; git clone https://code.google.com/p/leveldb/) - cd leveldb - (set -x; git checkout origin/windows) - cd .. - echo - fi - - # fetch and unpack boost-1.55 source - if [ ! -d boost ]; then - if [ ! -f _download/boost_1_55_0.7z ]; then - (set -x; mkdir -p _download) - (set -x; curl -o _download/boost_1_55_0.7z -L http://sourceforge.net/projects/boost/files/boost/1.55.0/boost_1_55_0.7z/download) - fi - (set -x; 7z x _download/boost_1_55_0.7z) - (set -x; mv boost_1_55_0 boost) - echo - fi - - # fetch and unpack icu - if [ ! -d icu ]; then - git svn clone -rHEAD http://source.icu-project.org/repos/icu/icu/tags/release-52-1 icu - cd icu - # patch for VS2013 and Windows Qt build - git am --3way --ignore-space-change -s ../cpp-ethereum/windows/patches/icu/0*.patch - cd .. - fi - - # fetch and unpack Qt 5.1.2 source - if [ ! -d Qt ]; then - if [ ! -f _download/qt-everywhere-opensource-src-5.2.1.zip ]; then - (set -x; mkdir -p _download) - (set -x; curl -o _download/qt-everywhere-opensource-src-5.2.1.zip -L http://download.qt-project.org/official_releases/qt/5.2/5.2.1/single/qt-everywhere-opensource-src-5.2.1.zip) - fi - (set -x; mkdir Qt) - cd Qt - (set -x; 7z x ../_download/qt-everywhere-opensource-src-5.2.1.zip) - (set -x; mv qt-everywhere-opensource-src-5.2.1 Src) - cd .. - echo - fi - - # fetch jom - if [ ! -f "Qt/jom/jom.exe" ]; then - if [ ! -f "_download/jom.zip" ]; then - (set -x; mkdir -p _download) - (set -x; curl -o "_download/jom.zip" -L http://download.qt-project.org/official_releases/jom/jom.zip) - fi - (set -x; mkdir -p Qt/jom) - cd Qt/jom - (set -x; 7z x ../../_download/jom.zip) - cd ../.. - echo - fi - - # fetch and unpack Lua binaries - if [ ! -d lua ]; then - if [ ! -f _download/lua-5.2.1_Win32_bin.zip ]; then - (set -x; mkdir -p _download) - (set -x; curl -o _download/lua-5.2.1_Win32_bin.zip -L http://sourceforge.net/projects/luabinaries/files/5.2.1/Executables/lua-5.2.1_Win32_bin.zip/download) - fi - (set -x; mkdir lua) - cd lua - (set -x; 7z x ../_download/lua-5.2.1_Win32_bin.zip lua52.exe lua52.dll) - (set -x; mv lua52.exe lua.exe) - cd .. - echo - fi -fi - -compile_boost() -{ - if [ $platform == "x64" ]; then - addressModel="address-model=64" - else - addressModel="" - fi - - if [ ! -d "stage/$platform" ]; then - targets="--with-filesystem --with-system --with-thread --with-date_time --with-regex --with-test" - (set -x; ./b2 -j4 --build-type=complete link=static runtime-link=shared variant=debug,release threading=multi $addressModel $targets stage) - (set -x; mv stage/lib stage/$platform) - fi -} - -if [[ ! $@ ]] || [ $1 == "compile-boost" ]; then - # bootstrap if b2 is missing - cd boost - if [ ! -f "b2.exe" ]; then - (set -x; cmd.exe /c bootstrap.bat) - fi - - # compile boost for x86 and x64 - platform="x64"; compile_boost - platform="Win32"; compile_boost - cd .. - echo -fi - -compile_icu() -{ - if [ ! -d lib_$platform ] || [ ! -d bin_$platform ]; then - (set -x; cmd.exe /c "..\\cpp-ethereum\\windows\\compile_icu.bat $platform") - if [ $platform == "x64" ]; then - icu_suff="64" - else - icu_suff="" - fi - rm -rf lib_$platform - rm -rf bin_$platform - mv lib$icu_suff lib_$platform - mv bin$icu_suff bin_$platform - fi -} - -if [[ ! $@ ]] || [ $1 == "compile-icu" ]; then - cd icu - platform="x64"; compile_icu - platform="Win32"; compile_icu - cd .. -fi - -compile_qt() -{ - if [ ! -d $platform ]; then - ( - set -x - - # copy icu dlls to Qt bin folder (this is so the Qt tools work without global adjustment to PATH) - mkdir -p $platform/qtbase/bin - cp -a ../icu/bin_$platform/*.dll $platform/qtbase/bin/ - - ( - # remove bash paths - set +x - path_remove_bin - set -x - - # compile qt - cmd.exe /c "..\\cpp-ethereum\\windows\\compile_qt.bat $platform" - ) - ) - fi -} - -if [[ ! $@ ]] || [ $1 == "compile-qt" ]; then - # compile Qt for x86 and x64 - cd Qt - platform="x64"; compile_qt - platform="Win32"; compile_qt - cd .. - echo -fi - -# finally run MS build -cd cpp-ethereum/windows -cmd.exe /c "compile_ethereum.bat" -cd .. \ No newline at end of file diff --git a/windows/compile_ethereum.bat b/windows/compile_ethereum.bat deleted file mode 100644 index 6aa93b155..000000000 --- a/windows/compile_ethereum.bat +++ /dev/null @@ -1,14 +0,0 @@ -@echo off -rem @file compile_ethereum.bat -rem @author Tim Hughes -rem @date 2014 -echo on - -rem : import VC environment -call "%VS120COMNTOOLS%\VsDevCmd.bat" - -rem : build for x64 -msbuild /maxcpucount /p:Configuration=Release;Platform=x64 Ethereum.sln - -rem : build for Win32 -msbuild /maxcpucount /p:Configuration=Release;Platform=Win32 Ethereum.sln diff --git a/windows/compile_icu.bat b/windows/compile_icu.bat deleted file mode 100644 index 93bd21976..000000000 --- a/windows/compile_icu.bat +++ /dev/null @@ -1,11 +0,0 @@ -@echo off -rem @file compile_icu.bat -rem @author Tim Hughes -rem @date 2014 -echo on - -rem : import VC environment -call "%VS120COMNTOOLS%\VsDevCmd.bat" - -rem : build for platform -msbuild /maxcpucount /p:Configuration=Release;Platform=%1% source/allinone/icu.sln diff --git a/windows/compile_qt.bat b/windows/compile_qt.bat deleted file mode 100644 index b11fd42d5..000000000 --- a/windows/compile_qt.bat +++ /dev/null @@ -1,51 +0,0 @@ -@echo off -rem @file compileqt.bat -rem @author Tim Hughes -rem @date 2014 - -rem : enable use prefix if we want to produce standalone Qt binaries -rem : off by default since this takes longer and duplicates all the headers -set USE_PREFIX=0 - -rem : echo commands so we can see what's going on -echo on - -rem : select platform and toolset from first argument -IF %1%==x64 (set PLATFORM=x64&set TOOLSET=x86_amd64&set) ELSE (set PLATFORM=Win32&set TOOLSET=x86=) - -rem : import VC environment vars -call "%VS120COMNTOOLS%\..\..\VC\vcvarsall.bat" %TOOLSET% - -rem : assume our root Qt dir is the current dir -set QT=%CD% - -set PATH=%QT%\Src\gnuwin32\bin;%PATH% - -rem : create the build folder and add the qtbase/bin folder to the PATH -if not exist %QT%\%PLATFORM%\Makefile ( - set DO_CONFIGURE=1 - mkdir %QT%\%PLATFORM% -) else ( - set DO_CONFIGURE=0 -) -if %USE_PREFIX%==1 ( - if not exist %QT%\%PLATFORM%-Build mkdir %QT%\%PLATFORM%-Build - if not exist %QT%\%PLATFORM%\qtbase mkdir %QT%\%PLATFORM%\qtbase - cd %QT%\%PLATFORM%-Build - set QT_PREFIX=-prefix %Qt%\%PLATFORM%\qtbase - set QT_TARGETS=install -) else ( - cd %QT%\%PLATFORM% - set QT_PREFIX= - set QT_TARGETS= -) -set PATH=%CD%\qtbase\bin;%PATH% - -rem : run Qt configure with desired settings -if %DO_CONFIGURE%==1 ( - call %QT%\Src\configure.bat %QT_PREFIX% -opensource -confirm-license -debug-and-release -opengl desktop -platform win32-msvc2013 -icu -I "%QT%\..\icu\include" -L "%QT%\..\icu\lib_%PLATFORM%" -nomake tests -nomake examples -) - -rem : compile and install module-qtbase -%QT%\jom\jom - diff --git a/windows/include/LibLevelDB/port/port.h b/windows/include/LibLevelDB/port/port.h deleted file mode 100644 index ce7ae19c4..000000000 --- a/windows/include/LibLevelDB/port/port.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2011 The LevelDB Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. See the AUTHORS file for names of contributors. - -#ifndef STORAGE_LEVELDB_PORT_PORT_H_ -#define STORAGE_LEVELDB_PORT_PORT_H_ - -#include - -// Include the appropriate platform specific file below. If you are -// porting to a new platform, see "port_example.h" for documentation -// of what the new port_.h file must provide. -#if defined(LEVELDB_PLATFORM_POSIX) -# include "port/port_posix.h" -#elif defined(LEVELDB_PLATFORM_CHROMIUM) -# include "port/port_chromium.h" -#elif defined(LEVELDB_PLATFORM_ANDROID) -# include "port/port_android.h" -#elif defined(LEVELDB_PLATFORM_WINDOWS) -# include "port/port_win.h" -#endif - -#endif // STORAGE_LEVELDB_PORT_PORT_H_ diff --git a/windows/include/LibLevelDB/unistd.h b/windows/include/LibLevelDB/unistd.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/windows/include/LibMiniUPnPc/miniupnpcstrings.h b/windows/include/LibMiniUPnPc/miniupnpcstrings.h deleted file mode 100644 index 364342ecf..000000000 --- a/windows/include/LibMiniUPnPc/miniupnpcstrings.h +++ /dev/null @@ -1,14 +0,0 @@ -/* $Id: miniupnpcstrings.h.in,v 1.4 2011/01/04 11:41:53 nanard Exp $ */ -/* Project: miniupnp - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * Author: Thomas Bernard - * Copyright (c) 2005-2011 Thomas Bernard - * This software is subjects to the conditions detailed - * in the LICENCE file provided within this distribution */ -#ifndef MINIUPNPCSTRINGS_H_INCLUDED -#define MINIUPNPCSTRINGS_H_INCLUDED - -#define OS_STRING "Windows" -#define MINIUPNPC_VERSION_STRING "1.9" - -#endif diff --git a/windows/moc.lua b/windows/moc.lua deleted file mode 100644 index 8a129eeae..000000000 --- a/windows/moc.lua +++ /dev/null @@ -1,38 +0,0 @@ - -local function quote(x) - return '"' .. x .. '"' -end - -local function toForward(x) - return x:gsub('\\', '/') -end - --- arguments are in this order -local cmd = arg[1] -local outFile = arg[2] -local includes = toForward(arg[3]) -local defines = arg[4] -local inFile = arg[5] - --- build list of includes -local includes2 = "" -for i in string.gmatch(includes, "[^;]+") do - includes2 = includes2.." -I "..quote(i) -end -includes = includes2; - --- build list of defines -local defines2 = "" -for i in string.gmatch(defines, "[^;]+") do - defines2 = defines2.." -D"..i -end -defines = defines2 - --- moc doesn't compile boost correctly, so skip those headers -workarounds=' -DBOOST_MP_CPP_INT_HPP -DBOOST_THREAD_WEK01082003_HPP' - --- build command -cmd = quote(cmd).." -o "..quote(outFile)..includes..defines..workarounds..' '..quote(inFile) -print(cmd) -os.execute(quote(cmd)) - diff --git a/windows/ncurses/include/ncurses/curses.h b/windows/ncurses/include/ncurses/curses.h deleted file mode 100644 index ff375d525..000000000 --- a/windows/ncurses/include/ncurses/curses.h +++ /dev/null @@ -1,1675 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2010,2011 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Zeyd M. Ben-Halim 1992,1995 * - * and: Eric S. Raymond * - * and: Thomas E. Dickey 1996-on * - ****************************************************************************/ - -/* $Id: curses.h.in,v 1.220 2011/01/22 19:47:20 tom Exp $ */ - -#ifndef __NCURSES_H -#define __NCURSES_H - -#define CURSES 1 -#define CURSES_H 1 - -/* These are defined only in curses.h, and are used for conditional compiles */ -#define NCURSES_VERSION_MAJOR 5 -#define NCURSES_VERSION_MINOR 9 -#define NCURSES_VERSION_PATCH 20110404 - -/* This is defined in more than one ncurses header, for identification */ -#undef NCURSES_VERSION -#define NCURSES_VERSION "5.9" - -/* - * Identify the mouse encoding version. - */ -#define NCURSES_MOUSE_VERSION 1 - -/* - * Definitions to facilitate DLL's. - */ -#include - -/* - * User-definable tweak to disable the include of . - */ -#ifndef NCURSES_ENABLE_STDBOOL_H -#define NCURSES_ENABLE_STDBOOL_H 1 -#endif - -/* - * NCURSES_ATTR_T is used to quiet compiler warnings when building ncurses - * configured using --disable-macros. - */ -#ifdef NCURSES_NOMACROS -#ifndef NCURSES_ATTR_T -#define NCURSES_ATTR_T attr_t -#endif -#endif /* NCURSES_NOMACROS */ - -#ifndef NCURSES_ATTR_T -#define NCURSES_ATTR_T int -#endif - -/* - * Expands to 'const' if ncurses is configured using --enable-const. Note that - * doing so makes it incompatible with other implementations of X/Open Curses. - */ -#undef NCURSES_CONST -#define NCURSES_CONST /*nothing*/ - -#undef NCURSES_INLINE -#define NCURSES_INLINE inline - -/* - * The internal type used for color values - */ -#undef NCURSES_COLOR_T -#define NCURSES_COLOR_T short - -/* - * Definition used to make WINDOW and similar structs opaque. - */ -#ifndef NCURSES_OPAQUE -#define NCURSES_OPAQUE 0 -#endif - -/* - * The reentrant code relies on the opaque setting, but adds features. - */ -#ifndef NCURSES_REENTRANT -#define NCURSES_REENTRANT 0 -#endif - -/* - * Control whether bindings for interop support are added. - */ -#undef NCURSES_INTEROP_FUNCS -#define NCURSES_INTEROP_FUNCS 0 - -/* - * The internal type used for window dimensions. - */ -#undef NCURSES_SIZE_T -#define NCURSES_SIZE_T short - -/* - * Control whether tparm() supports varargs or fixed-parameter list. - */ -#undef NCURSES_TPARM_VARARGS -#define NCURSES_TPARM_VARARGS 1 - -/* - * NCURSES_CH_T is used in building the library, but not used otherwise in - * this header file, since that would make the normal/wide-character versions - * of the header incompatible. - */ -#undef NCURSES_CH_T -#define NCURSES_CH_T chtype - -#if 0 && defined(_LP64) -typedef unsigned chtype; -typedef unsigned mmask_t; -#else -typedef unsigned long chtype; -typedef unsigned long mmask_t; -#endif - -/* - * We need FILE, etc. Include this before checking any feature symbols. - */ -#include - -/* - * With XPG4, you must define _XOPEN_SOURCE_EXTENDED, it is redundant (or - * conflicting) when _XOPEN_SOURCE is 500 or greater. - */ -#undef NCURSES_WIDECHAR -#if defined(_XOPEN_SOURCE_EXTENDED) || defined(_XPG5) -#define NCURSES_WIDECHAR -#endif - -#include /* we need va_list */ -#ifdef NCURSES_WIDECHAR -#include /* we want wchar_t */ -#endif - -/* X/Open and SVr4 specify that curses implements 'bool'. However, C++ may also - * implement it. If so, we must use the C++ compiler's type to avoid conflict - * with other interfaces. - * - * A further complication is that may declare 'bool' to be a - * different type, such as an enum which is not necessarily compatible with - * C++. If we have , make 'bool' a macro, so users may #undef it. - * Otherwise, let it remain a typedef to avoid conflicts with other #define's. - * In either case, make a typedef for NCURSES_BOOL which can be used if needed - * from either C or C++. - */ - -#undef TRUE -#define TRUE 1 - -#undef FALSE -#define FALSE 0 - -typedef unsigned char NCURSES_BOOL; - -#if defined(__cplusplus) /* __cplusplus, etc. */ - -/* use the C++ compiler's bool type */ -#define NCURSES_BOOL bool - -#else /* c89, c99, etc. */ - -#if NCURSES_ENABLE_STDBOOL_H -#include -/* use whatever the C compiler decides bool really is */ -#define NCURSES_BOOL bool -#else -/* there is no predefined bool - use our own */ -#undef bool -#define bool NCURSES_BOOL -#endif - -#endif /* !__cplusplus, etc. */ - -#ifdef __cplusplus -extern "C" { -#define NCURSES_CAST(type,value) static_cast(value) -#else -#define NCURSES_CAST(type,value) (type)(value) -#endif - -/* - * X/Open attributes. In the ncurses implementation, they are identical to the - * A_ attributes. - */ -#define WA_ATTRIBUTES A_ATTRIBUTES -#define WA_NORMAL A_NORMAL -#define WA_STANDOUT A_STANDOUT -#define WA_UNDERLINE A_UNDERLINE -#define WA_REVERSE A_REVERSE -#define WA_BLINK A_BLINK -#define WA_DIM A_DIM -#define WA_BOLD A_BOLD -#define WA_ALTCHARSET A_ALTCHARSET -#define WA_INVIS A_INVIS -#define WA_PROTECT A_PROTECT -#define WA_HORIZONTAL A_HORIZONTAL -#define WA_LEFT A_LEFT -#define WA_LOW A_LOW -#define WA_RIGHT A_RIGHT -#define WA_TOP A_TOP -#define WA_VERTICAL A_VERTICAL - -/* colors */ -#define COLOR_BLACK 0 -#define COLOR_RED 1 -#define COLOR_GREEN 2 -#define COLOR_YELLOW 3 -#define COLOR_BLUE 4 -#define COLOR_MAGENTA 5 -#define COLOR_CYAN 6 -#define COLOR_WHITE 7 - -/* line graphics */ - -#if 0 || NCURSES_REENTRANT -NCURSES_WRAPPED_VAR(chtype*, acs_map); -#define acs_map NCURSES_PUBLIC_VAR(acs_map()) -#else -extern NCURSES_EXPORT_VAR(chtype) acs_map[]; -#endif - -#define NCURSES_ACS(c) (acs_map[NCURSES_CAST(unsigned char,c)]) - -/* VT100 symbols begin here */ -#define ACS_ULCORNER NCURSES_ACS('l') /* upper left corner */ -#define ACS_LLCORNER NCURSES_ACS('m') /* lower left corner */ -#define ACS_URCORNER NCURSES_ACS('k') /* upper right corner */ -#define ACS_LRCORNER NCURSES_ACS('j') /* lower right corner */ -#define ACS_LTEE NCURSES_ACS('t') /* tee pointing right */ -#define ACS_RTEE NCURSES_ACS('u') /* tee pointing left */ -#define ACS_BTEE NCURSES_ACS('v') /* tee pointing up */ -#define ACS_TTEE NCURSES_ACS('w') /* tee pointing down */ -#define ACS_HLINE NCURSES_ACS('q') /* horizontal line */ -#define ACS_VLINE NCURSES_ACS('x') /* vertical line */ -#define ACS_PLUS NCURSES_ACS('n') /* large plus or crossover */ -#define ACS_S1 NCURSES_ACS('o') /* scan line 1 */ -#define ACS_S9 NCURSES_ACS('s') /* scan line 9 */ -#define ACS_DIAMOND NCURSES_ACS('`') /* diamond */ -#define ACS_CKBOARD NCURSES_ACS('a') /* checker board (stipple) */ -#define ACS_DEGREE NCURSES_ACS('f') /* degree symbol */ -#define ACS_PLMINUS NCURSES_ACS('g') /* plus/minus */ -#define ACS_BULLET NCURSES_ACS('~') /* bullet */ -/* Teletype 5410v1 symbols begin here */ -#define ACS_LARROW NCURSES_ACS(',') /* arrow pointing left */ -#define ACS_RARROW NCURSES_ACS('+') /* arrow pointing right */ -#define ACS_DARROW NCURSES_ACS('.') /* arrow pointing down */ -#define ACS_UARROW NCURSES_ACS('-') /* arrow pointing up */ -#define ACS_BOARD NCURSES_ACS('h') /* board of squares */ -#define ACS_LANTERN NCURSES_ACS('i') /* lantern symbol */ -#define ACS_BLOCK NCURSES_ACS('0') /* solid square block */ -/* - * These aren't documented, but a lot of System Vs have them anyway - * (you can spot pprryyzz{{||}} in a lot of AT&T terminfo strings). - * The ACS_names may not match AT&T's, our source didn't know them. - */ -#define ACS_S3 NCURSES_ACS('p') /* scan line 3 */ -#define ACS_S7 NCURSES_ACS('r') /* scan line 7 */ -#define ACS_LEQUAL NCURSES_ACS('y') /* less/equal */ -#define ACS_GEQUAL NCURSES_ACS('z') /* greater/equal */ -#define ACS_PI NCURSES_ACS('{') /* Pi */ -#define ACS_NEQUAL NCURSES_ACS('|') /* not equal */ -#define ACS_STERLING NCURSES_ACS('}') /* UK pound sign */ - -/* - * Line drawing ACS names are of the form ACS_trbl, where t is the top, r - * is the right, b is the bottom, and l is the left. t, r, b, and l might - * be B (blank), S (single), D (double), or T (thick). The subset defined - * here only uses B and S. - */ -#define ACS_BSSB ACS_ULCORNER -#define ACS_SSBB ACS_LLCORNER -#define ACS_BBSS ACS_URCORNER -#define ACS_SBBS ACS_LRCORNER -#define ACS_SBSS ACS_RTEE -#define ACS_SSSB ACS_LTEE -#define ACS_SSBS ACS_BTEE -#define ACS_BSSS ACS_TTEE -#define ACS_BSBS ACS_HLINE -#define ACS_SBSB ACS_VLINE -#define ACS_SSSS ACS_PLUS - -#undef ERR -#define ERR (-1) - -#undef OK -#define OK (0) - -/* values for the _flags member */ -#define _SUBWIN 0x01 /* is this a sub-window? */ -#define _ENDLINE 0x02 /* is the window flush right? */ -#define _FULLWIN 0x04 /* is the window full-screen? */ -#define _SCROLLWIN 0x08 /* bottom edge is at screen bottom? */ -#define _ISPAD 0x10 /* is this window a pad? */ -#define _HASMOVED 0x20 /* has cursor moved since last refresh? */ -#define _WRAPPED 0x40 /* cursor was just wrappped */ - -/* - * this value is used in the firstchar and lastchar fields to mark - * unchanged lines - */ -#define _NOCHANGE -1 - -/* - * this value is used in the oldindex field to mark lines created by insertions - * and scrolls. - */ -#define _NEWINDEX -1 - -typedef struct screen SCREEN; -typedef struct _win_st WINDOW; - -typedef chtype attr_t; /* ...must be at least as wide as chtype */ - -#ifdef NCURSES_WIDECHAR - -#if 0 -#ifdef mblen /* libutf8.h defines it w/o undefining first */ -#undef mblen -#endif -#include -#endif - -#if 0 -#include /* ...to get mbstate_t, etc. */ -#endif - -#if 0 -typedef unsigned short wchar_t; -#endif - -#if 0 -typedef unsigned int wint_t; -#endif - -/* - * cchar_t stores an array of CCHARW_MAX wide characters. The first is - * normally a spacing character. The others are non-spacing. If those - * (spacing and nonspacing) do not fill the array, a null L'\0' follows. - * Otherwise, a null is assumed to follow when extracting via getcchar(). - */ -#define CCHARW_MAX 5 -typedef struct -{ - attr_t attr; - wchar_t chars[CCHARW_MAX]; -#if 0 -#undef NCURSES_EXT_COLORS -#define NCURSES_EXT_COLORS 20110404 - int ext_color; /* color pair, must be more than 16-bits */ -#endif -} -cchar_t; - -#endif /* NCURSES_WIDECHAR */ - -#if !NCURSES_OPAQUE -struct ldat; - -struct _win_st -{ - NCURSES_SIZE_T _cury, _curx; /* current cursor position */ - - /* window location and size */ - NCURSES_SIZE_T _maxy, _maxx; /* maximums of x and y, NOT window size */ - NCURSES_SIZE_T _begy, _begx; /* screen coords of upper-left-hand corner */ - - short _flags; /* window state flags */ - - /* attribute tracking */ - attr_t _attrs; /* current attribute for non-space character */ - chtype _bkgd; /* current background char/attribute pair */ - - /* option values set by user */ - bool _notimeout; /* no time out on function-key entry? */ - bool _clear; /* consider all data in the window invalid? */ - bool _leaveok; /* OK to not reset cursor on exit? */ - bool _scroll; /* OK to scroll this window? */ - bool _idlok; /* OK to use insert/delete line? */ - bool _idcok; /* OK to use insert/delete char? */ - bool _immed; /* window in immed mode? (not yet used) */ - bool _sync; /* window in sync mode? */ - bool _use_keypad; /* process function keys into KEY_ symbols? */ - int _delay; /* 0 = nodelay, <0 = blocking, >0 = delay */ - - struct ldat *_line; /* the actual line data */ - - /* global screen state */ - NCURSES_SIZE_T _regtop; /* top line of scrolling region */ - NCURSES_SIZE_T _regbottom; /* bottom line of scrolling region */ - - /* these are used only if this is a sub-window */ - int _parx; /* x coordinate of this window in parent */ - int _pary; /* y coordinate of this window in parent */ - WINDOW *_parent; /* pointer to parent if a sub-window */ - - /* these are used only if this is a pad */ - struct pdat - { - NCURSES_SIZE_T _pad_y, _pad_x; - NCURSES_SIZE_T _pad_top, _pad_left; - NCURSES_SIZE_T _pad_bottom, _pad_right; - } _pad; - - NCURSES_SIZE_T _yoffset; /* real begy is _begy + _yoffset */ - -#ifdef NCURSES_WIDECHAR - cchar_t _bkgrnd; /* current background char/attribute pair */ -#if 0 - int _color; /* current color-pair for non-space character */ -#endif -#endif -}; -#endif /* NCURSES_OPAQUE */ - -/* - * This is an extension to support events... - */ -#if 1 -#ifdef NCURSES_WGETCH_EVENTS -#if !defined(__BEOS__) || defined(__HAIKU__) - /* Fix _nc_timed_wait() on BEOS... */ -# define NCURSES_EVENT_VERSION 1 -#endif /* !defined(__BEOS__) */ - -/* - * Bits to set in _nc_event.data.flags - */ -# define _NC_EVENT_TIMEOUT_MSEC 1 -# define _NC_EVENT_FILE 2 -# define _NC_EVENT_FILE_READABLE 2 -# if 0 /* Not supported yet... */ -# define _NC_EVENT_FILE_WRITABLE 4 -# define _NC_EVENT_FILE_EXCEPTION 8 -# endif - -typedef struct -{ - int type; - union - { - long timeout_msec; /* _NC_EVENT_TIMEOUT_MSEC */ - struct - { - unsigned int flags; - int fd; - unsigned int result; - } fev; /* _NC_EVENT_FILE */ - } data; -} _nc_event; - -typedef struct -{ - int count; - int result_flags; /* _NC_EVENT_TIMEOUT_MSEC or _NC_EVENT_FILE_READABLE */ - _nc_event *events[1]; -} _nc_eventlist; - -extern NCURSES_EXPORT(int) wgetch_events (WINDOW *, _nc_eventlist *); /* experimental */ -extern NCURSES_EXPORT(int) wgetnstr_events (WINDOW *,char *,int,_nc_eventlist *);/* experimental */ - -#endif /* NCURSES_WGETCH_EVENTS */ -#endif /* NCURSES_EXT_FUNCS */ - -/* - * GCC (and some other compilers) define '__attribute__'; we're using this - * macro to alert the compiler to flag inconsistencies in printf/scanf-like - * function calls. Just in case '__attribute__' isn't defined, make a dummy. - * Old versions of G++ do not accept it anyway, at least not consistently with - * GCC. - */ -#if !(defined(__GNUC__) || defined(__GNUG__) || defined(__attribute__)) -#define __attribute__(p) /* nothing */ -#endif - -/* - * We cannot define these in ncurses_cfg.h, since they require parameters to be - * passed (that is non-portable). If you happen to be using gcc with warnings - * enabled, define - * GCC_PRINTF - * GCC_SCANF - * to improve checking of calls to printw(), etc. - */ -#ifndef GCC_PRINTFLIKE -#if defined(GCC_PRINTF) && !defined(printf) -#define GCC_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var))) -#else -#define GCC_PRINTFLIKE(fmt,var) /*nothing*/ -#endif -#endif - -#ifndef GCC_SCANFLIKE -#if defined(GCC_SCANF) && !defined(scanf) -#define GCC_SCANFLIKE(fmt,var) __attribute__((format(scanf,fmt,var))) -#else -#define GCC_SCANFLIKE(fmt,var) /*nothing*/ -#endif -#endif - -#ifndef GCC_NORETURN -#define GCC_NORETURN /* nothing */ -#endif - -#ifndef GCC_UNUSED -#define GCC_UNUSED /* nothing */ -#endif - -/* - * Curses uses a helper function. Define our type for this to simplify - * extending it for the sp-funcs feature. - */ -typedef int (*NCURSES_OUTC)(int); - -/* - * Function prototypes. This is the complete X/Open Curses list of required - * functions. Those marked `generated' will have sources generated from the - * macro definitions later in this file, in order to satisfy XPG4.2 - * requirements. - */ - -extern NCURSES_EXPORT(int) addch (const chtype); /* generated */ -extern NCURSES_EXPORT(int) addchnstr (const chtype *, int); /* generated */ -extern NCURSES_EXPORT(int) addchstr (const chtype *); /* generated */ -extern NCURSES_EXPORT(int) addnstr (const char *, int); /* generated */ -extern NCURSES_EXPORT(int) addstr (const char *); /* generated */ -extern NCURSES_EXPORT(int) attroff (NCURSES_ATTR_T); /* generated */ -extern NCURSES_EXPORT(int) attron (NCURSES_ATTR_T); /* generated */ -extern NCURSES_EXPORT(int) attrset (NCURSES_ATTR_T); /* generated */ -extern NCURSES_EXPORT(int) attr_get (attr_t *, short *, void *); /* generated */ -extern NCURSES_EXPORT(int) attr_off (attr_t, void *); /* generated */ -extern NCURSES_EXPORT(int) attr_on (attr_t, void *); /* generated */ -extern NCURSES_EXPORT(int) attr_set (attr_t, short, void *); /* generated */ -extern NCURSES_EXPORT(int) baudrate (void); /* implemented */ -extern NCURSES_EXPORT(int) beep (void); /* implemented */ -extern NCURSES_EXPORT(int) bkgd (chtype); /* generated */ -extern NCURSES_EXPORT(void) bkgdset (chtype); /* generated */ -extern NCURSES_EXPORT(int) border (chtype,chtype,chtype,chtype,chtype,chtype,chtype,chtype); /* generated */ -extern NCURSES_EXPORT(int) box (WINDOW *, chtype, chtype); /* generated */ -extern NCURSES_EXPORT(bool) can_change_color (void); /* implemented */ -extern NCURSES_EXPORT(int) cbreak (void); /* implemented */ -extern NCURSES_EXPORT(int) chgat (int, attr_t, short, const void *); /* generated */ -extern NCURSES_EXPORT(int) clear (void); /* generated */ -extern NCURSES_EXPORT(int) clearok (WINDOW *,bool); /* implemented */ -extern NCURSES_EXPORT(int) clrtobot (void); /* generated */ -extern NCURSES_EXPORT(int) clrtoeol (void); /* generated */ -extern NCURSES_EXPORT(int) color_content (short,short*,short*,short*); /* implemented */ -extern NCURSES_EXPORT(int) color_set (short,void*); /* generated */ -extern NCURSES_EXPORT(int) COLOR_PAIR (int); /* generated */ -extern NCURSES_EXPORT(int) copywin (const WINDOW*,WINDOW*,int,int,int,int,int,int,int); /* implemented */ -extern NCURSES_EXPORT(int) curs_set (int); /* implemented */ -extern NCURSES_EXPORT(int) def_prog_mode (void); /* implemented */ -extern NCURSES_EXPORT(int) def_shell_mode (void); /* implemented */ -extern NCURSES_EXPORT(int) delay_output (int); /* implemented */ -extern NCURSES_EXPORT(int) delch (void); /* generated */ -extern NCURSES_EXPORT(void) delscreen (SCREEN *); /* implemented */ -extern NCURSES_EXPORT(int) delwin (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) deleteln (void); /* generated */ -extern NCURSES_EXPORT(WINDOW *) derwin (WINDOW *,int,int,int,int); /* implemented */ -extern NCURSES_EXPORT(int) doupdate (void); /* implemented */ -extern NCURSES_EXPORT(WINDOW *) dupwin (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) echo (void); /* implemented */ -extern NCURSES_EXPORT(int) echochar (const chtype); /* generated */ -extern NCURSES_EXPORT(int) erase (void); /* generated */ -extern NCURSES_EXPORT(int) endwin (void); /* implemented */ -extern NCURSES_EXPORT(char) erasechar (void); /* implemented */ -extern NCURSES_EXPORT(void) filter (void); /* implemented */ -extern NCURSES_EXPORT(int) flash (void); /* implemented */ -extern NCURSES_EXPORT(int) flushinp (void); /* implemented */ -extern NCURSES_EXPORT(chtype) getbkgd (WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) getch (void); /* generated */ -extern NCURSES_EXPORT(int) getnstr (char *, int); /* generated */ -extern NCURSES_EXPORT(int) getstr (char *); /* generated */ -extern NCURSES_EXPORT(WINDOW *) getwin (FILE *); /* implemented */ -extern NCURSES_EXPORT(int) halfdelay (int); /* implemented */ -extern NCURSES_EXPORT(bool) has_colors (void); /* implemented */ -extern NCURSES_EXPORT(bool) has_ic (void); /* implemented */ -extern NCURSES_EXPORT(bool) has_il (void); /* implemented */ -extern NCURSES_EXPORT(int) hline (chtype, int); /* generated */ -extern NCURSES_EXPORT(void) idcok (WINDOW *, bool); /* implemented */ -extern NCURSES_EXPORT(int) idlok (WINDOW *, bool); /* implemented */ -extern NCURSES_EXPORT(void) immedok (WINDOW *, bool); /* implemented */ -extern NCURSES_EXPORT(chtype) inch (void); /* generated */ -extern NCURSES_EXPORT(int) inchnstr (chtype *, int); /* generated */ -extern NCURSES_EXPORT(int) inchstr (chtype *); /* generated */ -extern NCURSES_EXPORT(WINDOW *) initscr (void); /* implemented */ -extern NCURSES_EXPORT(int) init_color (short,short,short,short); /* implemented */ -extern NCURSES_EXPORT(int) init_pair (short,short,short); /* implemented */ -extern NCURSES_EXPORT(int) innstr (char *, int); /* generated */ -extern NCURSES_EXPORT(int) insch (chtype); /* generated */ -extern NCURSES_EXPORT(int) insdelln (int); /* generated */ -extern NCURSES_EXPORT(int) insertln (void); /* generated */ -extern NCURSES_EXPORT(int) insnstr (const char *, int); /* generated */ -extern NCURSES_EXPORT(int) insstr (const char *); /* generated */ -extern NCURSES_EXPORT(int) instr (char *); /* generated */ -extern NCURSES_EXPORT(int) intrflush (WINDOW *,bool); /* implemented */ -extern NCURSES_EXPORT(bool) isendwin (void); /* implemented */ -extern NCURSES_EXPORT(bool) is_linetouched (WINDOW *,int); /* implemented */ -extern NCURSES_EXPORT(bool) is_wintouched (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(NCURSES_CONST char *) keyname (int); /* implemented */ -extern NCURSES_EXPORT(int) keypad (WINDOW *,bool); /* implemented */ -extern NCURSES_EXPORT(char) killchar (void); /* implemented */ -extern NCURSES_EXPORT(int) leaveok (WINDOW *,bool); /* implemented */ -extern NCURSES_EXPORT(char *) longname (void); /* implemented */ -extern NCURSES_EXPORT(int) meta (WINDOW *,bool); /* implemented */ -extern NCURSES_EXPORT(int) move (int, int); /* generated */ -extern NCURSES_EXPORT(int) mvaddch (int, int, const chtype); /* generated */ -extern NCURSES_EXPORT(int) mvaddchnstr (int, int, const chtype *, int); /* generated */ -extern NCURSES_EXPORT(int) mvaddchstr (int, int, const chtype *); /* generated */ -extern NCURSES_EXPORT(int) mvaddnstr (int, int, const char *, int); /* generated */ -extern NCURSES_EXPORT(int) mvaddstr (int, int, const char *); /* generated */ -extern NCURSES_EXPORT(int) mvchgat (int, int, int, attr_t, short, const void *); /* generated */ -extern NCURSES_EXPORT(int) mvcur (int,int,int,int); /* implemented */ -extern NCURSES_EXPORT(int) mvdelch (int, int); /* generated */ -extern NCURSES_EXPORT(int) mvderwin (WINDOW *, int, int); /* implemented */ -extern NCURSES_EXPORT(int) mvgetch (int, int); /* generated */ -extern NCURSES_EXPORT(int) mvgetnstr (int, int, char *, int); /* generated */ -extern NCURSES_EXPORT(int) mvgetstr (int, int, char *); /* generated */ -extern NCURSES_EXPORT(int) mvhline (int, int, chtype, int); /* generated */ -extern NCURSES_EXPORT(chtype) mvinch (int, int); /* generated */ -extern NCURSES_EXPORT(int) mvinchnstr (int, int, chtype *, int); /* generated */ -extern NCURSES_EXPORT(int) mvinchstr (int, int, chtype *); /* generated */ -extern NCURSES_EXPORT(int) mvinnstr (int, int, char *, int); /* generated */ -extern NCURSES_EXPORT(int) mvinsch (int, int, chtype); /* generated */ -extern NCURSES_EXPORT(int) mvinsnstr (int, int, const char *, int); /* generated */ -extern NCURSES_EXPORT(int) mvinsstr (int, int, const char *); /* generated */ -extern NCURSES_EXPORT(int) mvinstr (int, int, char *); /* generated */ -extern NCURSES_EXPORT(int) mvprintw (int,int, const char *,...) /* implemented */ - GCC_PRINTFLIKE(3,4); -extern NCURSES_EXPORT(int) mvscanw (int,int, NCURSES_CONST char *,...) /* implemented */ - GCC_SCANFLIKE(3,4); -extern NCURSES_EXPORT(int) mvvline (int, int, chtype, int); /* generated */ -extern NCURSES_EXPORT(int) mvwaddch (WINDOW *, int, int, const chtype); /* generated */ -extern NCURSES_EXPORT(int) mvwaddchnstr (WINDOW *, int, int, const chtype *, int);/* generated */ -extern NCURSES_EXPORT(int) mvwaddchstr (WINDOW *, int, int, const chtype *); /* generated */ -extern NCURSES_EXPORT(int) mvwaddnstr (WINDOW *, int, int, const char *, int); /* generated */ -extern NCURSES_EXPORT(int) mvwaddstr (WINDOW *, int, int, const char *); /* generated */ -extern NCURSES_EXPORT(int) mvwchgat (WINDOW *, int, int, int, attr_t, short, const void *);/* generated */ -extern NCURSES_EXPORT(int) mvwdelch (WINDOW *, int, int); /* generated */ -extern NCURSES_EXPORT(int) mvwgetch (WINDOW *, int, int); /* generated */ -extern NCURSES_EXPORT(int) mvwgetnstr (WINDOW *, int, int, char *, int); /* generated */ -extern NCURSES_EXPORT(int) mvwgetstr (WINDOW *, int, int, char *); /* generated */ -extern NCURSES_EXPORT(int) mvwhline (WINDOW *, int, int, chtype, int); /* generated */ -extern NCURSES_EXPORT(int) mvwin (WINDOW *,int,int); /* implemented */ -extern NCURSES_EXPORT(chtype) mvwinch (WINDOW *, int, int); /* generated */ -extern NCURSES_EXPORT(int) mvwinchnstr (WINDOW *, int, int, chtype *, int); /* generated */ -extern NCURSES_EXPORT(int) mvwinchstr (WINDOW *, int, int, chtype *); /* generated */ -extern NCURSES_EXPORT(int) mvwinnstr (WINDOW *, int, int, char *, int); /* generated */ -extern NCURSES_EXPORT(int) mvwinsch (WINDOW *, int, int, chtype); /* generated */ -extern NCURSES_EXPORT(int) mvwinsnstr (WINDOW *, int, int, const char *, int); /* generated */ -extern NCURSES_EXPORT(int) mvwinsstr (WINDOW *, int, int, const char *); /* generated */ -extern NCURSES_EXPORT(int) mvwinstr (WINDOW *, int, int, char *); /* generated */ -extern NCURSES_EXPORT(int) mvwprintw (WINDOW*,int,int, const char *,...) /* implemented */ - GCC_PRINTFLIKE(4,5); -extern NCURSES_EXPORT(int) mvwscanw (WINDOW *,int,int, NCURSES_CONST char *,...) /* implemented */ - GCC_SCANFLIKE(4,5); -extern NCURSES_EXPORT(int) mvwvline (WINDOW *,int, int, chtype, int); /* generated */ -extern NCURSES_EXPORT(int) napms (int); /* implemented */ -extern NCURSES_EXPORT(WINDOW *) newpad (int,int); /* implemented */ -extern NCURSES_EXPORT(SCREEN *) newterm (NCURSES_CONST char *,FILE *,FILE *); /* implemented */ -extern NCURSES_EXPORT(WINDOW *) newwin (int,int,int,int); /* implemented */ -extern NCURSES_EXPORT(int) nl (void); /* implemented */ -extern NCURSES_EXPORT(int) nocbreak (void); /* implemented */ -extern NCURSES_EXPORT(int) nodelay (WINDOW *,bool); /* implemented */ -extern NCURSES_EXPORT(int) noecho (void); /* implemented */ -extern NCURSES_EXPORT(int) nonl (void); /* implemented */ -extern NCURSES_EXPORT(void) noqiflush (void); /* implemented */ -extern NCURSES_EXPORT(int) noraw (void); /* implemented */ -extern NCURSES_EXPORT(int) notimeout (WINDOW *,bool); /* implemented */ -extern NCURSES_EXPORT(int) overlay (const WINDOW*,WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) overwrite (const WINDOW*,WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) pair_content (short,short*,short*); /* implemented */ -extern NCURSES_EXPORT(int) PAIR_NUMBER (int); /* generated */ -extern NCURSES_EXPORT(int) pechochar (WINDOW *, const chtype); /* implemented */ -extern NCURSES_EXPORT(int) pnoutrefresh (WINDOW*,int,int,int,int,int,int);/* implemented */ -extern NCURSES_EXPORT(int) prefresh (WINDOW *,int,int,int,int,int,int); /* implemented */ -extern NCURSES_EXPORT(int) printw (const char *,...) /* implemented */ - GCC_PRINTFLIKE(1,2); -extern NCURSES_EXPORT(int) putwin (WINDOW *, FILE *); /* implemented */ -extern NCURSES_EXPORT(void) qiflush (void); /* implemented */ -extern NCURSES_EXPORT(int) raw (void); /* implemented */ -extern NCURSES_EXPORT(int) redrawwin (WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) refresh (void); /* generated */ -extern NCURSES_EXPORT(int) resetty (void); /* implemented */ -extern NCURSES_EXPORT(int) reset_prog_mode (void); /* implemented */ -extern NCURSES_EXPORT(int) reset_shell_mode (void); /* implemented */ -extern NCURSES_EXPORT(int) ripoffline (int, int (*)(WINDOW *, int)); /* implemented */ -extern NCURSES_EXPORT(int) savetty (void); /* implemented */ -extern NCURSES_EXPORT(int) scanw (NCURSES_CONST char *,...) /* implemented */ - GCC_SCANFLIKE(1,2); -extern NCURSES_EXPORT(int) scr_dump (const char *); /* implemented */ -extern NCURSES_EXPORT(int) scr_init (const char *); /* implemented */ -extern NCURSES_EXPORT(int) scrl (int); /* generated */ -extern NCURSES_EXPORT(int) scroll (WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) scrollok (WINDOW *,bool); /* implemented */ -extern NCURSES_EXPORT(int) scr_restore (const char *); /* implemented */ -extern NCURSES_EXPORT(int) scr_set (const char *); /* implemented */ -extern NCURSES_EXPORT(int) setscrreg (int,int); /* generated */ -extern NCURSES_EXPORT(SCREEN *) set_term (SCREEN *); /* implemented */ -extern NCURSES_EXPORT(int) slk_attroff (const chtype); /* implemented */ -extern NCURSES_EXPORT(int) slk_attr_off (const attr_t, void *); /* generated:WIDEC */ -extern NCURSES_EXPORT(int) slk_attron (const chtype); /* implemented */ -extern NCURSES_EXPORT(int) slk_attr_on (attr_t,void*); /* generated:WIDEC */ -extern NCURSES_EXPORT(int) slk_attrset (const chtype); /* implemented */ -extern NCURSES_EXPORT(attr_t) slk_attr (void); /* implemented */ -extern NCURSES_EXPORT(int) slk_attr_set (const attr_t,short,void*); /* implemented */ -extern NCURSES_EXPORT(int) slk_clear (void); /* implemented */ -extern NCURSES_EXPORT(int) slk_color (short); /* implemented */ -extern NCURSES_EXPORT(int) slk_init (int); /* implemented */ -extern NCURSES_EXPORT(char *) slk_label (int); /* implemented */ -extern NCURSES_EXPORT(int) slk_noutrefresh (void); /* implemented */ -extern NCURSES_EXPORT(int) slk_refresh (void); /* implemented */ -extern NCURSES_EXPORT(int) slk_restore (void); /* implemented */ -extern NCURSES_EXPORT(int) slk_set (int,const char *,int); /* implemented */ -extern NCURSES_EXPORT(int) slk_touch (void); /* implemented */ -extern NCURSES_EXPORT(int) standout (void); /* generated */ -extern NCURSES_EXPORT(int) standend (void); /* generated */ -extern NCURSES_EXPORT(int) start_color (void); /* implemented */ -extern NCURSES_EXPORT(WINDOW *) subpad (WINDOW *, int, int, int, int); /* implemented */ -extern NCURSES_EXPORT(WINDOW *) subwin (WINDOW *, int, int, int, int); /* implemented */ -extern NCURSES_EXPORT(int) syncok (WINDOW *, bool); /* implemented */ -extern NCURSES_EXPORT(chtype) termattrs (void); /* implemented */ -extern NCURSES_EXPORT(char *) termname (void); /* implemented */ -extern NCURSES_EXPORT(void) timeout (int); /* generated */ -extern NCURSES_EXPORT(int) touchline (WINDOW *, int, int); /* generated */ -extern NCURSES_EXPORT(int) touchwin (WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) typeahead (int); /* implemented */ -extern NCURSES_EXPORT(int) ungetch (int); /* implemented */ -extern NCURSES_EXPORT(int) untouchwin (WINDOW *); /* generated */ -extern NCURSES_EXPORT(void) use_env (bool); /* implemented */ -extern NCURSES_EXPORT(int) vidattr (chtype); /* implemented */ -extern NCURSES_EXPORT(int) vidputs (chtype, NCURSES_OUTC); /* implemented */ -extern NCURSES_EXPORT(int) vline (chtype, int); /* generated */ -extern NCURSES_EXPORT(int) vwprintw (WINDOW *, const char *,va_list); /* implemented */ -extern NCURSES_EXPORT(int) vw_printw (WINDOW *, const char *,va_list); /* generated */ -extern NCURSES_EXPORT(int) vwscanw (WINDOW *, NCURSES_CONST char *,va_list); /* implemented */ -extern NCURSES_EXPORT(int) vw_scanw (WINDOW *, NCURSES_CONST char *,va_list); /* generated */ -extern NCURSES_EXPORT(int) waddch (WINDOW *, const chtype); /* implemented */ -extern NCURSES_EXPORT(int) waddchnstr (WINDOW *,const chtype *,int); /* implemented */ -extern NCURSES_EXPORT(int) waddchstr (WINDOW *,const chtype *); /* generated */ -extern NCURSES_EXPORT(int) waddnstr (WINDOW *,const char *,int); /* implemented */ -extern NCURSES_EXPORT(int) waddstr (WINDOW *,const char *); /* generated */ -extern NCURSES_EXPORT(int) wattron (WINDOW *, int); /* generated */ -extern NCURSES_EXPORT(int) wattroff (WINDOW *, int); /* generated */ -extern NCURSES_EXPORT(int) wattrset (WINDOW *, int); /* generated */ -extern NCURSES_EXPORT(int) wattr_get (WINDOW *, attr_t *, short *, void *); /* generated */ -extern NCURSES_EXPORT(int) wattr_on (WINDOW *, attr_t, void *); /* implemented */ -extern NCURSES_EXPORT(int) wattr_off (WINDOW *, attr_t, void *); /* implemented */ -extern NCURSES_EXPORT(int) wattr_set (WINDOW *, attr_t, short, void *); /* generated */ -extern NCURSES_EXPORT(int) wbkgd (WINDOW *, chtype); /* implemented */ -extern NCURSES_EXPORT(void) wbkgdset (WINDOW *,chtype); /* implemented */ -extern NCURSES_EXPORT(int) wborder (WINDOW *,chtype,chtype,chtype,chtype,chtype,chtype,chtype,chtype); /* implemented */ -extern NCURSES_EXPORT(int) wchgat (WINDOW *, int, attr_t, short, const void *);/* implemented */ -extern NCURSES_EXPORT(int) wclear (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) wclrtobot (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) wclrtoeol (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) wcolor_set (WINDOW*,short,void*); /* implemented */ -extern NCURSES_EXPORT(void) wcursyncup (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) wdelch (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) wdeleteln (WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) wechochar (WINDOW *, const chtype); /* implemented */ -extern NCURSES_EXPORT(int) werase (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) wgetch (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) wgetnstr (WINDOW *,char *,int); /* implemented */ -extern NCURSES_EXPORT(int) wgetstr (WINDOW *, char *); /* generated */ -extern NCURSES_EXPORT(int) whline (WINDOW *, chtype, int); /* implemented */ -extern NCURSES_EXPORT(chtype) winch (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) winchnstr (WINDOW *, chtype *, int); /* implemented */ -extern NCURSES_EXPORT(int) winchstr (WINDOW *, chtype *); /* generated */ -extern NCURSES_EXPORT(int) winnstr (WINDOW *, char *, int); /* implemented */ -extern NCURSES_EXPORT(int) winsch (WINDOW *, chtype); /* implemented */ -extern NCURSES_EXPORT(int) winsdelln (WINDOW *,int); /* implemented */ -extern NCURSES_EXPORT(int) winsertln (WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) winsnstr (WINDOW *, const char *,int); /* implemented */ -extern NCURSES_EXPORT(int) winsstr (WINDOW *, const char *); /* generated */ -extern NCURSES_EXPORT(int) winstr (WINDOW *, char *); /* generated */ -extern NCURSES_EXPORT(int) wmove (WINDOW *,int,int); /* implemented */ -extern NCURSES_EXPORT(int) wnoutrefresh (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) wprintw (WINDOW *, const char *,...) /* implemented */ - GCC_PRINTFLIKE(2,3); -extern NCURSES_EXPORT(int) wredrawln (WINDOW *,int,int); /* implemented */ -extern NCURSES_EXPORT(int) wrefresh (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) wscanw (WINDOW *, NCURSES_CONST char *,...) /* implemented */ - GCC_SCANFLIKE(2,3); -extern NCURSES_EXPORT(int) wscrl (WINDOW *,int); /* implemented */ -extern NCURSES_EXPORT(int) wsetscrreg (WINDOW *,int,int); /* implemented */ -extern NCURSES_EXPORT(int) wstandout (WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) wstandend (WINDOW *); /* generated */ -extern NCURSES_EXPORT(void) wsyncdown (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(void) wsyncup (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(void) wtimeout (WINDOW *,int); /* implemented */ -extern NCURSES_EXPORT(int) wtouchln (WINDOW *,int,int,int); /* implemented */ -extern NCURSES_EXPORT(int) wvline (WINDOW *,chtype,int); /* implemented */ - -/* - * These are also declared in : - */ -extern NCURSES_EXPORT(int) tigetflag (NCURSES_CONST char *); /* implemented */ -extern NCURSES_EXPORT(int) tigetnum (NCURSES_CONST char *); /* implemented */ -extern NCURSES_EXPORT(char *) tigetstr (NCURSES_CONST char *); /* implemented */ -extern NCURSES_EXPORT(int) putp (const char *); /* implemented */ - -#if NCURSES_TPARM_VARARGS -extern NCURSES_EXPORT(char *) tparm (NCURSES_CONST char *, ...); /* special */ -#else -extern NCURSES_EXPORT(char *) tparm (NCURSES_CONST char *, long,long,long,long,long,long,long,long,long); /* special */ -extern NCURSES_EXPORT(char *) tparm_varargs (NCURSES_CONST char *, ...); /* special */ -#endif - -extern NCURSES_EXPORT(char *) tiparm (const char *, ...); /* special */ - -/* - * These functions are not in X/Open, but we use them in macro definitions: - */ -extern NCURSES_EXPORT(int) getattrs (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) getcurx (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) getcury (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) getbegx (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) getbegy (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) getmaxx (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) getmaxy (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) getparx (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) getpary (const WINDOW *); /* generated */ - -/* - * vid_attr() was implemented originally based on a draft of X/Open curses. - */ -#ifndef NCURSES_WIDECHAR -#define vid_attr(a,pair,opts) vidattr(a) -#endif - -/* - * These functions are extensions - not in X/Open Curses. - */ -#if 1 -#undef NCURSES_EXT_FUNCS -#define NCURSES_EXT_FUNCS 20110404 -typedef int (*NCURSES_WINDOW_CB)(WINDOW *, void *); -typedef int (*NCURSES_SCREEN_CB)(SCREEN *, void *); -extern NCURSES_EXPORT(bool) is_term_resized (int, int); -extern NCURSES_EXPORT(char *) keybound (int, int); -extern NCURSES_EXPORT(const char *) curses_version (void); -extern NCURSES_EXPORT(int) assume_default_colors (int, int); -extern NCURSES_EXPORT(int) define_key (const char *, int); -extern NCURSES_EXPORT(int) get_escdelay (void); -extern NCURSES_EXPORT(int) key_defined (const char *); -extern NCURSES_EXPORT(int) keyok (int, bool); -extern NCURSES_EXPORT(int) resize_term (int, int); -extern NCURSES_EXPORT(int) resizeterm (int, int); -extern NCURSES_EXPORT(int) set_escdelay (int); -extern NCURSES_EXPORT(int) set_tabsize (int); -extern NCURSES_EXPORT(int) use_default_colors (void); -extern NCURSES_EXPORT(int) use_extended_names (bool); -extern NCURSES_EXPORT(int) use_legacy_coding (int); -extern NCURSES_EXPORT(int) use_screen (SCREEN *, NCURSES_SCREEN_CB, void *); -extern NCURSES_EXPORT(int) use_window (WINDOW *, NCURSES_WINDOW_CB, void *); -extern NCURSES_EXPORT(int) wresize (WINDOW *, int, int); -extern NCURSES_EXPORT(void) nofilter(void); - -/* - * These extensions provide access to information stored in the WINDOW even - * when NCURSES_OPAQUE is set: - */ -extern NCURSES_EXPORT(WINDOW *) wgetparent (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_cleared (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_idcok (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_idlok (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_immedok (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_keypad (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_leaveok (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_nodelay (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_notimeout (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_pad (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_scrollok (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_subwin (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_syncok (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) wgetscrreg (const WINDOW *, int *, int *); /* generated */ - -#else -#define curses_version() NCURSES_VERSION -#endif - -/* - * Extra extension-functions, which pass a SCREEN pointer rather than using - * a global variable SP. - */ -#if 1 -#undef NCURSES_SP_FUNCS -#define NCURSES_SP_FUNCS 20110404 -#define NCURSES_SP_NAME(name) name##_sp - -/* Define the sp-funcs helper function */ -#define NCURSES_SP_OUTC NCURSES_SP_NAME(NCURSES_OUTC) -typedef int (*NCURSES_SP_OUTC)(SCREEN*, int); - -extern NCURSES_EXPORT(SCREEN *) new_prescr (void); /* implemented:SP_FUNC */ - -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(baudrate) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(beep) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(bool) NCURSES_SP_NAME(can_change_color) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(cbreak) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(curs_set) (SCREEN*, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(color_content) (SCREEN*, short, short*, short*, short*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(def_prog_mode) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(def_shell_mode) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(delay_output) (SCREEN*, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(doupdate) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(echo) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(endwin) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(char) NCURSES_SP_NAME(erasechar) (SCREEN*);/* implemented:SP_FUNC */ -extern NCURSES_EXPORT(void) NCURSES_SP_NAME(filter) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(flash) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(flushinp) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(WINDOW *) NCURSES_SP_NAME(getwin) (SCREEN*, FILE *); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(halfdelay) (SCREEN*, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(bool) NCURSES_SP_NAME(has_colors) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(bool) NCURSES_SP_NAME(has_ic) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(bool) NCURSES_SP_NAME(has_il) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(init_color) (SCREEN*, short, short, short, short); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(init_pair) (SCREEN*, short, short, short); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(intrflush) (SCREEN*, WINDOW*, bool); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(bool) NCURSES_SP_NAME(isendwin) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(NCURSES_CONST char *) NCURSES_SP_NAME(keyname) (SCREEN*, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(char) NCURSES_SP_NAME(killchar) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(char *) NCURSES_SP_NAME(longname) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(mvcur) (SCREEN*, int, int, int, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(napms) (SCREEN*, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(WINDOW *) NCURSES_SP_NAME(newpad) (SCREEN*, int, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(SCREEN *) NCURSES_SP_NAME(newterm) (SCREEN*, NCURSES_CONST char *, FILE *, FILE *); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(WINDOW *) NCURSES_SP_NAME(newwin) (SCREEN*, int, int, int, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(nl) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(nocbreak) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(noecho) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(nonl) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(void) NCURSES_SP_NAME(noqiflush) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(noraw) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(pair_content) (SCREEN*, short, short*, short*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(void) NCURSES_SP_NAME(qiflush) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(raw) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(reset_prog_mode) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(reset_shell_mode) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(resetty) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(ripoffline) (SCREEN*, int, int (*)(WINDOW *, int)); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(savetty) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(scr_init) (SCREEN*, const char *); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(scr_restore) (SCREEN*, const char *); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(scr_set) (SCREEN*, const char *); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_attroff) (SCREEN*, const chtype); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_attron) (SCREEN*, const chtype); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_attrset) (SCREEN*, const chtype); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(attr_t) NCURSES_SP_NAME(slk_attr) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_attr_set) (SCREEN*, const attr_t, short, void*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_clear) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_color) (SCREEN*, short); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_init) (SCREEN*, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(char *) NCURSES_SP_NAME(slk_label) (SCREEN*, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_noutrefresh) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_refresh) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_restore) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_set) (SCREEN*, int, const char *, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_touch) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(start_color) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(chtype) NCURSES_SP_NAME(termattrs) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(char *) NCURSES_SP_NAME(termname) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(typeahead) (SCREEN*, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(ungetch) (SCREEN*, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(void) NCURSES_SP_NAME(use_env) (SCREEN*, bool); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(vidattr) (SCREEN*, chtype); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(vidputs) (SCREEN*, chtype, NCURSES_SP_OUTC); /* implemented:SP_FUNC */ -#if 1 -extern NCURSES_EXPORT(char *) NCURSES_SP_NAME(keybound) (SCREEN*, int, int); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(assume_default_colors) (SCREEN*, int, int); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(define_key) (SCREEN*, const char *, int); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(get_escdelay) (SCREEN*); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(bool) NCURSES_SP_NAME(is_term_resized) (SCREEN*, int, int); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(key_defined) (SCREEN*, const char *); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(keyok) (SCREEN*, int, bool); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(void) NCURSES_SP_NAME(nofilter) (SCREEN*); /* implemented */ /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(resize_term) (SCREEN*, int, int); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(resizeterm) (SCREEN*, int, int); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(set_escdelay) (SCREEN*, int); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(set_tabsize) (SCREEN*, int); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(use_default_colors) (SCREEN*); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(use_legacy_coding) (SCREEN*, int); /* implemented:EXT_SP_FUNC */ -#endif -#else -#undef NCURSES_SP_FUNCS -#define NCURSES_SP_FUNCS 0 -#define NCURSES_SP_NAME(name) name -#define NCURSES_SP_OUTC NCURSES_OUTC -#endif - -/* attributes */ - -#define NCURSES_ATTR_SHIFT 8 -#define NCURSES_BITS(mask,shift) ((mask) << ((shift) + NCURSES_ATTR_SHIFT)) - -#define A_NORMAL (1UL - 1UL) -#define A_ATTRIBUTES NCURSES_BITS(~(1UL - 1UL),0) -#define A_CHARTEXT (NCURSES_BITS(1UL,0) - 1UL) -#define A_COLOR NCURSES_BITS(((1UL) << 8) - 1UL,0) -#define A_STANDOUT NCURSES_BITS(1UL,8) -#define A_UNDERLINE NCURSES_BITS(1UL,9) -#define A_REVERSE NCURSES_BITS(1UL,10) -#define A_BLINK NCURSES_BITS(1UL,11) -#define A_DIM NCURSES_BITS(1UL,12) -#define A_BOLD NCURSES_BITS(1UL,13) -#define A_ALTCHARSET NCURSES_BITS(1UL,14) -#define A_INVIS NCURSES_BITS(1UL,15) -#define A_PROTECT NCURSES_BITS(1UL,16) -#define A_HORIZONTAL NCURSES_BITS(1UL,17) -#define A_LEFT NCURSES_BITS(1UL,18) -#define A_LOW NCURSES_BITS(1UL,19) -#define A_RIGHT NCURSES_BITS(1UL,20) -#define A_TOP NCURSES_BITS(1UL,21) -#define A_VERTICAL NCURSES_BITS(1UL,22) - -/* - * Most of the pseudo functions are macros that either provide compatibility - * with older versions of curses, or provide inline functionality to improve - * performance. - */ - -/* - * These pseudo functions are always implemented as macros: - */ - -#define getyx(win,y,x) (y = getcury(win), x = getcurx(win)) -#define getbegyx(win,y,x) (y = getbegy(win), x = getbegx(win)) -#define getmaxyx(win,y,x) (y = getmaxy(win), x = getmaxx(win)) -#define getparyx(win,y,x) (y = getpary(win), x = getparx(win)) - -#define getsyx(y,x) do { if (newscr) { \ - if (is_leaveok(newscr)) \ - (y) = (x) = -1; \ - else \ - getyx(newscr,(y), (x)); \ - } \ - } while(0) - -#define setsyx(y,x) do { if (newscr) { \ - if ((y) == -1 && (x) == -1) \ - leaveok(newscr, TRUE); \ - else { \ - leaveok(newscr, FALSE); \ - wmove(newscr, (y), (x)); \ - } \ - } \ - } while(0) - -#ifndef NCURSES_NOMACROS - -/* - * These miscellaneous pseudo functions are provided for compatibility: - */ - -#define wgetstr(w, s) wgetnstr(w, s, -1) -#define getnstr(s, n) wgetnstr(stdscr, s, n) - -#define setterm(term) setupterm(term, 1, (int *)0) - -#define fixterm() reset_prog_mode() -#define resetterm() reset_shell_mode() -#define saveterm() def_prog_mode() -#define crmode() cbreak() -#define nocrmode() nocbreak() -#define gettmode() - -/* It seems older SYSV curses versions define these */ -#if !NCURSES_OPAQUE -#define getattrs(win) NCURSES_CAST(int, (win) ? (win)->_attrs : A_NORMAL) -#define getcurx(win) ((win) ? (win)->_curx : ERR) -#define getcury(win) ((win) ? (win)->_cury : ERR) -#define getbegx(win) ((win) ? (win)->_begx : ERR) -#define getbegy(win) ((win) ? (win)->_begy : ERR) -#define getmaxx(win) ((win) ? ((win)->_maxx + 1) : ERR) -#define getmaxy(win) ((win) ? ((win)->_maxy + 1) : ERR) -#define getparx(win) ((win) ? (win)->_parx : ERR) -#define getpary(win) ((win) ? (win)->_pary : ERR) -#endif /* NCURSES_OPAQUE */ - -#define wstandout(win) (wattrset(win,A_STANDOUT)) -#define wstandend(win) (wattrset(win,A_NORMAL)) - -#define wattron(win,at) wattr_on(win, NCURSES_CAST(attr_t, at), NULL) -#define wattroff(win,at) wattr_off(win, NCURSES_CAST(attr_t, at), NULL) - -#if !NCURSES_OPAQUE -#if defined(NCURSES_WIDECHAR) && 0 -#define wattrset(win,at) ((win) \ - ? ((win)->_color = PAIR_NUMBER(at), \ - (win)->_attrs = NCURSES_CAST(attr_t, at), \ - OK) \ - : ERR) -#else -#define wattrset(win,at) ((win) \ - ? ((win)->_attrs = NCURSES_CAST(attr_t, at), \ - OK) \ - : ERR) -#endif -#endif /* NCURSES_OPAQUE */ - -#define scroll(win) wscrl(win,1) - -#define touchwin(win) wtouchln((win), 0, getmaxy(win), 1) -#define touchline(win, s, c) wtouchln((win), s, c, 1) -#define untouchwin(win) wtouchln((win), 0, getmaxy(win), 0) - -#define box(win, v, h) wborder(win, v, v, h, h, 0, 0, 0, 0) -#define border(ls, rs, ts, bs, tl, tr, bl, br) wborder(stdscr, ls, rs, ts, bs, tl, tr, bl, br) -#define hline(ch, n) whline(stdscr, ch, n) -#define vline(ch, n) wvline(stdscr, ch, n) - -#define winstr(w, s) winnstr(w, s, -1) -#define winchstr(w, s) winchnstr(w, s, -1) -#define winsstr(w, s) winsnstr(w, s, -1) - -#if !NCURSES_OPAQUE -#define redrawwin(win) wredrawln(win, 0, (win)->_maxy+1) -#endif /* NCURSES_OPAQUE */ - -#define waddstr(win,str) waddnstr(win,str,-1) -#define waddchstr(win,str) waddchnstr(win,str,-1) - -/* - * These apply to the first 256 color pairs. - */ -#define COLOR_PAIR(n) NCURSES_BITS(n, 0) -#define PAIR_NUMBER(a) (NCURSES_CAST(int,((NCURSES_CAST(unsigned long,a) & A_COLOR) >> NCURSES_ATTR_SHIFT))) - -/* - * pseudo functions for standard screen - */ - -#define addch(ch) waddch(stdscr,ch) -#define addchnstr(str,n) waddchnstr(stdscr,str,n) -#define addchstr(str) waddchstr(stdscr,str) -#define addnstr(str,n) waddnstr(stdscr,str,n) -#define addstr(str) waddnstr(stdscr,str,-1) -#define attroff(at) wattroff(stdscr,at) -#define attron(at) wattron(stdscr,at) -#define attrset(at) wattrset(stdscr,at) -#define attr_get(ap,cp,o) wattr_get(stdscr,ap,cp,o) -#define attr_off(a,o) wattr_off(stdscr,a,o) -#define attr_on(a,o) wattr_on(stdscr,a,o) -#define attr_set(a,c,o) wattr_set(stdscr,a,c,o) -#define bkgd(ch) wbkgd(stdscr,ch) -#define bkgdset(ch) wbkgdset(stdscr,ch) -#define chgat(n,a,c,o) wchgat(stdscr,n,a,c,o) -#define clear() wclear(stdscr) -#define clrtobot() wclrtobot(stdscr) -#define clrtoeol() wclrtoeol(stdscr) -#define color_set(c,o) wcolor_set(stdscr,c,o) -#define delch() wdelch(stdscr) -#define deleteln() winsdelln(stdscr,-1) -#define echochar(c) wechochar(stdscr,c) -#define erase() werase(stdscr) -#define getch() wgetch(stdscr) -#define getstr(str) wgetstr(stdscr,str) -#define inch() winch(stdscr) -#define inchnstr(s,n) winchnstr(stdscr,s,n) -#define inchstr(s) winchstr(stdscr,s) -#define innstr(s,n) winnstr(stdscr,s,n) -#define insch(c) winsch(stdscr,c) -#define insdelln(n) winsdelln(stdscr,n) -#define insertln() winsdelln(stdscr,1) -#define insnstr(s,n) winsnstr(stdscr,s,n) -#define insstr(s) winsstr(stdscr,s) -#define instr(s) winstr(stdscr,s) -#define move(y,x) wmove(stdscr,y,x) -#define refresh() wrefresh(stdscr) -#define scrl(n) wscrl(stdscr,n) -#define setscrreg(t,b) wsetscrreg(stdscr,t,b) -#define standend() wstandend(stdscr) -#define standout() wstandout(stdscr) -#define timeout(delay) wtimeout(stdscr,delay) -#define wdeleteln(win) winsdelln(win,-1) -#define winsertln(win) winsdelln(win,1) - -/* - * mv functions - */ - -#define mvwaddch(win,y,x,ch) (wmove(win,y,x) == ERR ? ERR : waddch(win,ch)) -#define mvwaddchnstr(win,y,x,str,n) (wmove(win,y,x) == ERR ? ERR : waddchnstr(win,str,n)) -#define mvwaddchstr(win,y,x,str) (wmove(win,y,x) == ERR ? ERR : waddchnstr(win,str,-1)) -#define mvwaddnstr(win,y,x,str,n) (wmove(win,y,x) == ERR ? ERR : waddnstr(win,str,n)) -#define mvwaddstr(win,y,x,str) (wmove(win,y,x) == ERR ? ERR : waddnstr(win,str,-1)) -#define mvwdelch(win,y,x) (wmove(win,y,x) == ERR ? ERR : wdelch(win)) -#define mvwchgat(win,y,x,n,a,c,o) (wmove(win,y,x) == ERR ? ERR : wchgat(win,n,a,c,o)) -#define mvwgetch(win,y,x) (wmove(win,y,x) == ERR ? ERR : wgetch(win)) -#define mvwgetnstr(win,y,x,str,n) (wmove(win,y,x) == ERR ? ERR : wgetnstr(win,str,n)) -#define mvwgetstr(win,y,x,str) (wmove(win,y,x) == ERR ? ERR : wgetstr(win,str)) -#define mvwhline(win,y,x,c,n) (wmove(win,y,x) == ERR ? ERR : whline(win,c,n)) -#define mvwinch(win,y,x) (wmove(win,y,x) == ERR ? NCURSES_CAST(chtype, ERR) : winch(win)) -#define mvwinchnstr(win,y,x,s,n) (wmove(win,y,x) == ERR ? ERR : winchnstr(win,s,n)) -#define mvwinchstr(win,y,x,s) (wmove(win,y,x) == ERR ? ERR : winchstr(win,s)) -#define mvwinnstr(win,y,x,s,n) (wmove(win,y,x) == ERR ? ERR : winnstr(win,s,n)) -#define mvwinsch(win,y,x,c) (wmove(win,y,x) == ERR ? ERR : winsch(win,c)) -#define mvwinsnstr(win,y,x,s,n) (wmove(win,y,x) == ERR ? ERR : winsnstr(win,s,n)) -#define mvwinsstr(win,y,x,s) (wmove(win,y,x) == ERR ? ERR : winsstr(win,s)) -#define mvwinstr(win,y,x,s) (wmove(win,y,x) == ERR ? ERR : winstr(win,s)) -#define mvwvline(win,y,x,c,n) (wmove(win,y,x) == ERR ? ERR : wvline(win,c,n)) - -#define mvaddch(y,x,ch) mvwaddch(stdscr,y,x,ch) -#define mvaddchnstr(y,x,str,n) mvwaddchnstr(stdscr,y,x,str,n) -#define mvaddchstr(y,x,str) mvwaddchstr(stdscr,y,x,str) -#define mvaddnstr(y,x,str,n) mvwaddnstr(stdscr,y,x,str,n) -#define mvaddstr(y,x,str) mvwaddstr(stdscr,y,x,str) -#define mvchgat(y,x,n,a,c,o) mvwchgat(stdscr,y,x,n,a,c,o) -#define mvdelch(y,x) mvwdelch(stdscr,y,x) -#define mvgetch(y,x) mvwgetch(stdscr,y,x) -#define mvgetnstr(y,x,str,n) mvwgetnstr(stdscr,y,x,str,n) -#define mvgetstr(y,x,str) mvwgetstr(stdscr,y,x,str) -#define mvhline(y,x,c,n) mvwhline(stdscr,y,x,c,n) -#define mvinch(y,x) mvwinch(stdscr,y,x) -#define mvinchnstr(y,x,s,n) mvwinchnstr(stdscr,y,x,s,n) -#define mvinchstr(y,x,s) mvwinchstr(stdscr,y,x,s) -#define mvinnstr(y,x,s,n) mvwinnstr(stdscr,y,x,s,n) -#define mvinsch(y,x,c) mvwinsch(stdscr,y,x,c) -#define mvinsnstr(y,x,s,n) mvwinsnstr(stdscr,y,x,s,n) -#define mvinsstr(y,x,s) mvwinsstr(stdscr,y,x,s) -#define mvinstr(y,x,s) mvwinstr(stdscr,y,x,s) -#define mvvline(y,x,c,n) mvwvline(stdscr,y,x,c,n) - -/* - * Some wide-character functions can be implemented without the extensions. - */ -#if !NCURSES_OPAQUE -#define getbkgd(win) ((win)->_bkgd) -#endif /* NCURSES_OPAQUE */ - -#define slk_attr_off(a,v) ((v) ? ERR : slk_attroff(a)) -#define slk_attr_on(a,v) ((v) ? ERR : slk_attron(a)) - -#if !NCURSES_OPAQUE -#if defined(NCURSES_WIDECHAR) && 0 -#define wattr_set(win,a,p,opts) ((win)->_attrs = ((a) & ~A_COLOR), \ - (win)->_color = (p), \ - OK) -#define wattr_get(win,a,p,opts) ((void)((a) != (void *)0 && (*(a) = (win)->_attrs)), \ - (void)((p) != (void *)0 && (*(p) = (short)(win)->_color)), \ - OK) -#else -#define wattr_set(win,a,p,opts) ((win)->_attrs = (((a) & ~A_COLOR) | (attr_t)COLOR_PAIR(p)), OK) -#define wattr_get(win,a,p,opts) ((void)((a) != (void *)0 && (*(a) = (win)->_attrs)), \ - (void)((p) != (void *)0 && (*(p) = (short)PAIR_NUMBER((win)->_attrs))), \ - OK) -#endif -#endif /* NCURSES_OPAQUE */ - -/* - * X/Open curses deprecates SVr4 vwprintw/vwscanw, which are supposed to use - * varargs.h. It adds new calls vw_printw/vw_scanw, which are supposed to - * use POSIX stdarg.h. The ncurses versions of vwprintw/vwscanw already - * use stdarg.h, so... - */ -#define vw_printw vwprintw -#define vw_scanw vwscanw - -/* - * Export fallback function for use in C++ binding. - */ -#if !1 -#define vsscanf(a,b,c) _nc_vsscanf(a,b,c) -NCURSES_EXPORT(int) vsscanf(const char *, const char *, va_list); -#endif - -/* - * These macros are extensions - not in X/Open Curses. - */ -#if 1 -#if !NCURSES_OPAQUE -#define is_cleared(win) ((win) ? (win)->_clear : FALSE) -#define is_idcok(win) ((win) ? (win)->_idcok : FALSE) -#define is_idlok(win) ((win) ? (win)->_idlok : FALSE) -#define is_immedok(win) ((win) ? (win)->_immed : FALSE) -#define is_keypad(win) ((win) ? (win)->_use_keypad : FALSE) -#define is_leaveok(win) ((win) ? (win)->_leaveok : FALSE) -#define is_nodelay(win) ((win) ? ((win)->_delay == 0) : FALSE) -#define is_notimeout(win) ((win) ? (win)->_notimeout : FALSE) -#define is_pad(win) ((win) ? ((win)->_flags & _ISPAD) != 0 : FALSE) -#define is_scrollok(win) ((win) ? (win)->_scroll : FALSE) -#define is_subwin(win) ((win) ? ((win)->_flags & _SUBWIN) != 0 : FALSE) -#define is_syncok(win) ((win) ? (win)->_sync : FALSE) -#define wgetparent(win) ((win) ? (win)->_parent : 0) -#define wgetscrreg(win,t,b) ((win) ? (*(t) = (win)->_regtop, *(b) = (win)->_regbottom, OK) : ERR) -#endif -#endif - -#endif /* NCURSES_NOMACROS */ - -/* - * Public variables. - * - * Notes: - * a. ESCDELAY was an undocumented feature under AIX curses. - * It gives the ESC expire time in milliseconds. - * b. ttytype is needed for backward compatibility - */ -#if NCURSES_REENTRANT - -NCURSES_WRAPPED_VAR(WINDOW *, curscr); -NCURSES_WRAPPED_VAR(WINDOW *, newscr); -NCURSES_WRAPPED_VAR(WINDOW *, stdscr); -NCURSES_WRAPPED_VAR(char *, ttytype); -NCURSES_WRAPPED_VAR(int, COLORS); -NCURSES_WRAPPED_VAR(int, COLOR_PAIRS); -NCURSES_WRAPPED_VAR(int, COLS); -NCURSES_WRAPPED_VAR(int, ESCDELAY); -NCURSES_WRAPPED_VAR(int, LINES); -NCURSES_WRAPPED_VAR(int, TABSIZE); - -#define curscr NCURSES_PUBLIC_VAR(curscr()) -#define newscr NCURSES_PUBLIC_VAR(newscr()) -#define stdscr NCURSES_PUBLIC_VAR(stdscr()) -#define ttytype NCURSES_PUBLIC_VAR(ttytype()) -#define COLORS NCURSES_PUBLIC_VAR(COLORS()) -#define COLOR_PAIRS NCURSES_PUBLIC_VAR(COLOR_PAIRS()) -#define COLS NCURSES_PUBLIC_VAR(COLS()) -#define ESCDELAY NCURSES_PUBLIC_VAR(ESCDELAY()) -#define LINES NCURSES_PUBLIC_VAR(LINES()) -#define TABSIZE NCURSES_PUBLIC_VAR(TABSIZE()) - -#else - -extern NCURSES_EXPORT_VAR(WINDOW *) curscr; -extern NCURSES_EXPORT_VAR(WINDOW *) newscr; -extern NCURSES_EXPORT_VAR(WINDOW *) stdscr; -extern NCURSES_EXPORT_VAR(char) ttytype[]; -extern NCURSES_EXPORT_VAR(int) COLORS; -extern NCURSES_EXPORT_VAR(int) COLOR_PAIRS; -extern NCURSES_EXPORT_VAR(int) COLS; -extern NCURSES_EXPORT_VAR(int) ESCDELAY; -extern NCURSES_EXPORT_VAR(int) LINES; -extern NCURSES_EXPORT_VAR(int) TABSIZE; - -#endif - -/* - * Pseudo-character tokens outside ASCII range. The curses wgetch() function - * will return any given one of these only if the corresponding k- capability - * is defined in your terminal's terminfo entry. - * - * Some keys (KEY_A1, etc) are arranged like this: - * a1 up a3 - * left b2 right - * c1 down c3 - * - * A few key codes do not depend upon the terminfo entry. - */ -#define KEY_CODE_YES 0400 /* A wchar_t contains a key code */ -#define KEY_MIN 0401 /* Minimum curses key */ -#define KEY_BREAK 0401 /* Break key (unreliable) */ -#define KEY_SRESET 0530 /* Soft (partial) reset (unreliable) */ -#define KEY_RESET 0531 /* Reset or hard reset (unreliable) */ -/* - * These definitions were generated by ./MKkey_defs.sh ./Caps - */ -#define KEY_DOWN 0402 /* down-arrow key */ -#define KEY_UP 0403 /* up-arrow key */ -#define KEY_LEFT 0404 /* left-arrow key */ -#define KEY_RIGHT 0405 /* right-arrow key */ -#define KEY_HOME 0406 /* home key */ -#define KEY_BACKSPACE 0407 /* backspace key */ -#define KEY_F0 0410 /* Function keys. Space for 64 */ -#define KEY_F(n) (KEY_F0+(n)) /* Value of function key n */ -#define KEY_DL 0510 /* delete-line key */ -#define KEY_IL 0511 /* insert-line key */ -#define KEY_DC 0512 /* delete-character key */ -#define KEY_IC 0513 /* insert-character key */ -#define KEY_EIC 0514 /* sent by rmir or smir in insert mode */ -#define KEY_CLEAR 0515 /* clear-screen or erase key */ -#define KEY_EOS 0516 /* clear-to-end-of-screen key */ -#define KEY_EOL 0517 /* clear-to-end-of-line key */ -#define KEY_SF 0520 /* scroll-forward key */ -#define KEY_SR 0521 /* scroll-backward key */ -#define KEY_NPAGE 0522 /* next-page key */ -#define KEY_PPAGE 0523 /* previous-page key */ -#define KEY_STAB 0524 /* set-tab key */ -#define KEY_CTAB 0525 /* clear-tab key */ -#define KEY_CATAB 0526 /* clear-all-tabs key */ -#define KEY_ENTER 0527 /* enter/send key */ -#define KEY_PRINT 0532 /* print key */ -#define KEY_LL 0533 /* lower-left key (home down) */ -#define KEY_A1 0534 /* upper left of keypad */ -#define KEY_A3 0535 /* upper right of keypad */ -#define KEY_B2 0536 /* center of keypad */ -#define KEY_C1 0537 /* lower left of keypad */ -#define KEY_C3 0540 /* lower right of keypad */ -#define KEY_BTAB 0541 /* back-tab key */ -#define KEY_BEG 0542 /* begin key */ -#define KEY_CANCEL 0543 /* cancel key */ -#define KEY_CLOSE 0544 /* close key */ -#define KEY_COMMAND 0545 /* command key */ -#define KEY_COPY 0546 /* copy key */ -#define KEY_CREATE 0547 /* create key */ -#define KEY_END 0550 /* end key */ -#define KEY_EXIT 0551 /* exit key */ -#define KEY_FIND 0552 /* find key */ -#define KEY_HELP 0553 /* help key */ -#define KEY_MARK 0554 /* mark key */ -#define KEY_MESSAGE 0555 /* message key */ -#define KEY_MOVE 0556 /* move key */ -#define KEY_NEXT 0557 /* next key */ -#define KEY_OPEN 0560 /* open key */ -#define KEY_OPTIONS 0561 /* options key */ -#define KEY_PREVIOUS 0562 /* previous key */ -#define KEY_REDO 0563 /* redo key */ -#define KEY_REFERENCE 0564 /* reference key */ -#define KEY_REFRESH 0565 /* refresh key */ -#define KEY_REPLACE 0566 /* replace key */ -#define KEY_RESTART 0567 /* restart key */ -#define KEY_RESUME 0570 /* resume key */ -#define KEY_SAVE 0571 /* save key */ -#define KEY_SBEG 0572 /* shifted begin key */ -#define KEY_SCANCEL 0573 /* shifted cancel key */ -#define KEY_SCOMMAND 0574 /* shifted command key */ -#define KEY_SCOPY 0575 /* shifted copy key */ -#define KEY_SCREATE 0576 /* shifted create key */ -#define KEY_SDC 0577 /* shifted delete-character key */ -#define KEY_SDL 0600 /* shifted delete-line key */ -#define KEY_SELECT 0601 /* select key */ -#define KEY_SEND 0602 /* shifted end key */ -#define KEY_SEOL 0603 /* shifted clear-to-end-of-line key */ -#define KEY_SEXIT 0604 /* shifted exit key */ -#define KEY_SFIND 0605 /* shifted find key */ -#define KEY_SHELP 0606 /* shifted help key */ -#define KEY_SHOME 0607 /* shifted home key */ -#define KEY_SIC 0610 /* shifted insert-character key */ -#define KEY_SLEFT 0611 /* shifted left-arrow key */ -#define KEY_SMESSAGE 0612 /* shifted message key */ -#define KEY_SMOVE 0613 /* shifted move key */ -#define KEY_SNEXT 0614 /* shifted next key */ -#define KEY_SOPTIONS 0615 /* shifted options key */ -#define KEY_SPREVIOUS 0616 /* shifted previous key */ -#define KEY_SPRINT 0617 /* shifted print key */ -#define KEY_SREDO 0620 /* shifted redo key */ -#define KEY_SREPLACE 0621 /* shifted replace key */ -#define KEY_SRIGHT 0622 /* shifted right-arrow key */ -#define KEY_SRSUME 0623 /* shifted resume key */ -#define KEY_SSAVE 0624 /* shifted save key */ -#define KEY_SSUSPEND 0625 /* shifted suspend key */ -#define KEY_SUNDO 0626 /* shifted undo key */ -#define KEY_SUSPEND 0627 /* suspend key */ -#define KEY_UNDO 0630 /* undo key */ -#define KEY_MOUSE 0631 /* Mouse event has occurred */ -#define KEY_RESIZE 0632 /* Terminal resize event */ -#define KEY_EVENT 0633 /* We were interrupted by an event */ - -#define KEY_MAX 0777 /* Maximum key value is 0633 */ -/* $Id: curses.tail,v 1.20 2010/03/28 19:10:55 tom Exp $ */ -/* - * vile:cmode: - * This file is part of ncurses, designed to be appended after curses.h.in - * (see that file for the relevant copyright). - */ - -/* mouse interface */ - -#if NCURSES_MOUSE_VERSION > 1 -#define NCURSES_MOUSE_MASK(b,m) ((m) << (((b) - 1) * 5)) -#else -#define NCURSES_MOUSE_MASK(b,m) ((m) << (((b) - 1) * 6)) -#endif - -#define NCURSES_BUTTON_RELEASED 001L -#define NCURSES_BUTTON_PRESSED 002L -#define NCURSES_BUTTON_CLICKED 004L -#define NCURSES_DOUBLE_CLICKED 010L -#define NCURSES_TRIPLE_CLICKED 020L -#define NCURSES_RESERVED_EVENT 040L - -/* event masks */ -#define BUTTON1_RELEASED NCURSES_MOUSE_MASK(1, NCURSES_BUTTON_RELEASED) -#define BUTTON1_PRESSED NCURSES_MOUSE_MASK(1, NCURSES_BUTTON_PRESSED) -#define BUTTON1_CLICKED NCURSES_MOUSE_MASK(1, NCURSES_BUTTON_CLICKED) -#define BUTTON1_DOUBLE_CLICKED NCURSES_MOUSE_MASK(1, NCURSES_DOUBLE_CLICKED) -#define BUTTON1_TRIPLE_CLICKED NCURSES_MOUSE_MASK(1, NCURSES_TRIPLE_CLICKED) - -#define BUTTON2_RELEASED NCURSES_MOUSE_MASK(2, NCURSES_BUTTON_RELEASED) -#define BUTTON2_PRESSED NCURSES_MOUSE_MASK(2, NCURSES_BUTTON_PRESSED) -#define BUTTON2_CLICKED NCURSES_MOUSE_MASK(2, NCURSES_BUTTON_CLICKED) -#define BUTTON2_DOUBLE_CLICKED NCURSES_MOUSE_MASK(2, NCURSES_DOUBLE_CLICKED) -#define BUTTON2_TRIPLE_CLICKED NCURSES_MOUSE_MASK(2, NCURSES_TRIPLE_CLICKED) - -#define BUTTON3_RELEASED NCURSES_MOUSE_MASK(3, NCURSES_BUTTON_RELEASED) -#define BUTTON3_PRESSED NCURSES_MOUSE_MASK(3, NCURSES_BUTTON_PRESSED) -#define BUTTON3_CLICKED NCURSES_MOUSE_MASK(3, NCURSES_BUTTON_CLICKED) -#define BUTTON3_DOUBLE_CLICKED NCURSES_MOUSE_MASK(3, NCURSES_DOUBLE_CLICKED) -#define BUTTON3_TRIPLE_CLICKED NCURSES_MOUSE_MASK(3, NCURSES_TRIPLE_CLICKED) - -#define BUTTON4_RELEASED NCURSES_MOUSE_MASK(4, NCURSES_BUTTON_RELEASED) -#define BUTTON4_PRESSED NCURSES_MOUSE_MASK(4, NCURSES_BUTTON_PRESSED) -#define BUTTON4_CLICKED NCURSES_MOUSE_MASK(4, NCURSES_BUTTON_CLICKED) -#define BUTTON4_DOUBLE_CLICKED NCURSES_MOUSE_MASK(4, NCURSES_DOUBLE_CLICKED) -#define BUTTON4_TRIPLE_CLICKED NCURSES_MOUSE_MASK(4, NCURSES_TRIPLE_CLICKED) - -/* - * In 32 bits the version-1 scheme does not provide enough space for a 5th - * button, unless we choose to change the ABI by omitting the reserved-events. - */ -#if NCURSES_MOUSE_VERSION > 1 - -#define BUTTON5_RELEASED NCURSES_MOUSE_MASK(5, NCURSES_BUTTON_RELEASED) -#define BUTTON5_PRESSED NCURSES_MOUSE_MASK(5, NCURSES_BUTTON_PRESSED) -#define BUTTON5_CLICKED NCURSES_MOUSE_MASK(5, NCURSES_BUTTON_CLICKED) -#define BUTTON5_DOUBLE_CLICKED NCURSES_MOUSE_MASK(5, NCURSES_DOUBLE_CLICKED) -#define BUTTON5_TRIPLE_CLICKED NCURSES_MOUSE_MASK(5, NCURSES_TRIPLE_CLICKED) - -#define BUTTON_CTRL NCURSES_MOUSE_MASK(6, 0001L) -#define BUTTON_SHIFT NCURSES_MOUSE_MASK(6, 0002L) -#define BUTTON_ALT NCURSES_MOUSE_MASK(6, 0004L) -#define REPORT_MOUSE_POSITION NCURSES_MOUSE_MASK(6, 0010L) - -#else - -#define BUTTON1_RESERVED_EVENT NCURSES_MOUSE_MASK(1, NCURSES_RESERVED_EVENT) -#define BUTTON2_RESERVED_EVENT NCURSES_MOUSE_MASK(2, NCURSES_RESERVED_EVENT) -#define BUTTON3_RESERVED_EVENT NCURSES_MOUSE_MASK(3, NCURSES_RESERVED_EVENT) -#define BUTTON4_RESERVED_EVENT NCURSES_MOUSE_MASK(4, NCURSES_RESERVED_EVENT) - -#define BUTTON_CTRL NCURSES_MOUSE_MASK(5, 0001L) -#define BUTTON_SHIFT NCURSES_MOUSE_MASK(5, 0002L) -#define BUTTON_ALT NCURSES_MOUSE_MASK(5, 0004L) -#define REPORT_MOUSE_POSITION NCURSES_MOUSE_MASK(5, 0010L) - -#endif - -#define ALL_MOUSE_EVENTS (REPORT_MOUSE_POSITION - 1) - -/* macros to extract single event-bits from masks */ -#define BUTTON_RELEASE(e, x) ((e) & NCURSES_MOUSE_MASK(x, 001)) -#define BUTTON_PRESS(e, x) ((e) & NCURSES_MOUSE_MASK(x, 002)) -#define BUTTON_CLICK(e, x) ((e) & NCURSES_MOUSE_MASK(x, 004)) -#define BUTTON_DOUBLE_CLICK(e, x) ((e) & NCURSES_MOUSE_MASK(x, 010)) -#define BUTTON_TRIPLE_CLICK(e, x) ((e) & NCURSES_MOUSE_MASK(x, 020)) -#define BUTTON_RESERVED_EVENT(e, x) ((e) & NCURSES_MOUSE_MASK(x, 040)) - -typedef struct -{ - short id; /* ID to distinguish multiple devices */ - int x, y, z; /* event coordinates (character-cell) */ - mmask_t bstate; /* button state bits */ -} -MEVENT; - -extern NCURSES_EXPORT(bool) has_mouse(void); -extern NCURSES_EXPORT(int) getmouse (MEVENT *); -extern NCURSES_EXPORT(int) ungetmouse (MEVENT *); -extern NCURSES_EXPORT(mmask_t) mousemask (mmask_t, mmask_t *); -extern NCURSES_EXPORT(bool) wenclose (const WINDOW *, int, int); -extern NCURSES_EXPORT(int) mouseinterval (int); -extern NCURSES_EXPORT(bool) wmouse_trafo (const WINDOW*, int*, int*, bool); -extern NCURSES_EXPORT(bool) mouse_trafo (int*, int*, bool); /* generated */ - -#if NCURSES_SP_FUNCS -extern NCURSES_EXPORT(bool) NCURSES_SP_NAME(has_mouse) (SCREEN*); -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(getmouse) (SCREEN*, MEVENT *); -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(ungetmouse) (SCREEN*,MEVENT *); -extern NCURSES_EXPORT(mmask_t) NCURSES_SP_NAME(mousemask) (SCREEN*, mmask_t, mmask_t *); -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(mouseinterval) (SCREEN*, int); -#endif - -#define mouse_trafo(y,x,to_screen) wmouse_trafo(stdscr,y,x,to_screen) - -/* other non-XSI functions */ - -extern NCURSES_EXPORT(int) mcprint (char *, int); /* direct data to printer */ -extern NCURSES_EXPORT(int) has_key (int); /* do we have given key? */ - -#if NCURSES_SP_FUNCS -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(has_key) (SCREEN*, int); /* do we have given key? */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(mcprint) (SCREEN*, char *, int); /* direct data to printer */ -#endif - -/* Debugging : use with libncurses_g.a */ - -extern NCURSES_EXPORT(void) _tracef (const char *, ...) GCC_PRINTFLIKE(1,2); -extern NCURSES_EXPORT(void) _tracedump (const char *, WINDOW *); -extern NCURSES_EXPORT(char *) _traceattr (attr_t); -extern NCURSES_EXPORT(char *) _traceattr2 (int, chtype); -extern NCURSES_EXPORT(char *) _nc_tracebits (void); -extern NCURSES_EXPORT(char *) _tracechar (int); -extern NCURSES_EXPORT(char *) _tracechtype (chtype); -extern NCURSES_EXPORT(char *) _tracechtype2 (int, chtype); -#ifdef NCURSES_WIDECHAR -#define _tracech_t _tracecchar_t -extern NCURSES_EXPORT(char *) _tracecchar_t (const cchar_t *); -#define _tracech_t2 _tracecchar_t2 -extern NCURSES_EXPORT(char *) _tracecchar_t2 (int, const cchar_t *); -#else -#define _tracech_t _tracechtype -#define _tracech_t2 _tracechtype2 -#endif -extern NCURSES_EXPORT(char *) _tracemouse (const MEVENT *); -extern NCURSES_EXPORT(void) trace (const unsigned int); - -/* trace masks */ -#define TRACE_DISABLE 0x0000 /* turn off tracing */ -#define TRACE_TIMES 0x0001 /* trace user and system times of updates */ -#define TRACE_TPUTS 0x0002 /* trace tputs calls */ -#define TRACE_UPDATE 0x0004 /* trace update actions, old & new screens */ -#define TRACE_MOVE 0x0008 /* trace cursor moves and scrolls */ -#define TRACE_CHARPUT 0x0010 /* trace all character outputs */ -#define TRACE_ORDINARY 0x001F /* trace all update actions */ -#define TRACE_CALLS 0x0020 /* trace all curses calls */ -#define TRACE_VIRTPUT 0x0040 /* trace virtual character puts */ -#define TRACE_IEVENT 0x0080 /* trace low-level input processing */ -#define TRACE_BITS 0x0100 /* trace state of TTY control bits */ -#define TRACE_ICALLS 0x0200 /* trace internal/nested calls */ -#define TRACE_CCALLS 0x0400 /* trace per-character calls */ -#define TRACE_DATABASE 0x0800 /* trace read/write of terminfo/termcap data */ -#define TRACE_ATTRS 0x1000 /* trace attribute updates */ - -#define TRACE_SHIFT 13 /* number of bits in the trace masks */ -#define TRACE_MAXIMUM ((1 << TRACE_SHIFT) - 1) /* maximum trace level */ - -#if defined(TRACE) || defined(NCURSES_TEST) -extern NCURSES_EXPORT_VAR(int) _nc_optimize_enable; /* enable optimizations */ -extern NCURSES_EXPORT(const char *) _nc_visbuf (const char *); -#define OPTIMIZE_MVCUR 0x01 /* cursor movement optimization */ -#define OPTIMIZE_HASHMAP 0x02 /* diff hashing to detect scrolls */ -#define OPTIMIZE_SCROLL 0x04 /* scroll optimization */ -#define OPTIMIZE_ALL 0xff /* enable all optimizations (dflt) */ -#endif - -#include - -#ifdef __cplusplus - -#ifndef NCURSES_NOMACROS - -/* these names conflict with STL */ -#undef box -#undef clear -#undef erase -#undef move -#undef refresh - -#endif /* NCURSES_NOMACROS */ - -} -#endif - -#endif /* __NCURSES_H */ diff --git a/windows/ncurses/include/ncurses/cursesapp.h b/windows/ncurses/include/ncurses/cursesapp.h deleted file mode 100644 index f619c1f04..000000000 --- a/windows/ncurses/include/ncurses/cursesapp.h +++ /dev/null @@ -1,176 +0,0 @@ -// * This makes emacs happy -*-Mode: C++;-*- -/**************************************************************************** - * Copyright (c) 1998-2003,2005 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Juergen Pfeifer, 1997 * - ****************************************************************************/ - -// $Id: cursesapp.h,v 1.11 2005/05/28 21:57:44 tom Exp $ - -#ifndef NCURSES_CURSESAPP_H_incl -#define NCURSES_CURSESAPP_H_incl - -#include - -class NCURSES_IMPEXP NCursesApplication { -public: - typedef struct _slk_link { // This structure is used to maintain - struct _slk_link* prev; // a stack of SLKs - Soft_Label_Key_Set* SLKs; - } SLK_Link; -private: - static int rinit(NCursesWindow& w); // Internal Init function for title - static NCursesApplication* theApp; // Global ref. to the application - - static SLK_Link* slk_stack; - -protected: - static NCursesWindow* titleWindow; // The Title Window (if any) - - bool b_Colors; // Is this a color application? - NCursesWindow* Root_Window; // This is the stdscr equiv. - - // Initialization of attributes; - // Rewrite this in your derived class if you prefer other settings - virtual void init(bool bColors); - - // The number of lines for the title window. Default is no title window - // You may rewrite this in your derived class - virtual int titlesize() const { - return 0; - } - - // This method is called to put something into the title window initially - // You may rewrite this in your derived class - virtual void title() { - } - - // The layout used for the Soft Label Keys. Default is to have no SLKs. - // You may rewrite this in your derived class - virtual Soft_Label_Key_Set::Label_Layout useSLKs() const { - return Soft_Label_Key_Set::None; - } - - // This method is called to initialize the SLKs. Default is nothing. - // You may rewrite this in your derived class - virtual void init_labels(Soft_Label_Key_Set& S) const { - } - - // Your derived class must implement this method. The return value must - // be the exit value of your application. - virtual int run() = 0; - - // The constructor is protected, so you may use it in your derived - // class constructor. The argument tells whether or not you want colors. - NCursesApplication(bool wantColors = FALSE); - - NCursesApplication& operator=(const NCursesApplication& rhs) - { - if (this != &rhs) { - *this = rhs; - } - return *this; - } - - NCursesApplication(const NCursesApplication& rhs) - : b_Colors(rhs.b_Colors), - Root_Window(rhs.Root_Window) - { - } - -public: - virtual ~NCursesApplication(); - - // Get a pointer to the current application object - static NCursesApplication* getApplication() { - return theApp; - } - - // This method runs the application and returns its exit value - int operator()(void); - - // Process the commandline arguments. The default implementation simply - // ignores them. Your derived class may rewrite this. - virtual void handleArgs(int argc, char* argv[]) { - } - - // Does this application use colors? - inline bool useColors() const { - return b_Colors; - } - - // Push the Key Set S onto the SLK Stack. S then becomes the current set - // of Soft Labelled Keys. - void push(Soft_Label_Key_Set& S); - - // Throw away the current set of SLKs and make the previous one the - // new current set. - bool pop(); - - // Retrieve the current set of Soft Labelled Keys. - Soft_Label_Key_Set* top() const; - - // Attributes to use for menu and forms foregrounds - virtual chtype foregrounds() const { - return b_Colors ? COLOR_PAIR(1) : A_BOLD; - } - - // Attributes to use for menu and forms backgrounds - virtual chtype backgrounds() const { - return b_Colors ? COLOR_PAIR(2) : A_NORMAL; - } - - // Attributes to use for inactive (menu) elements - virtual chtype inactives() const { - return b_Colors ? (COLOR_PAIR(3)|A_DIM) : A_DIM; - } - - // Attributes to use for (form) labels and SLKs - virtual chtype labels() const { - return b_Colors ? COLOR_PAIR(4) : A_NORMAL; - } - - // Attributes to use for form backgrounds - virtual chtype dialog_backgrounds() const { - return b_Colors ? COLOR_PAIR(4) : A_NORMAL; - } - - // Attributes to use as default for (form) window backgrounds - virtual chtype window_backgrounds() const { - return b_Colors ? COLOR_PAIR(5) : A_NORMAL; - } - - // Attributes to use for the title window - virtual chtype screen_titles() const { - return b_Colors ? COLOR_PAIR(6) : A_BOLD; - } - -}; - -#endif /* NCURSES_CURSESAPP_H_incl */ diff --git a/windows/ncurses/include/ncurses/cursesf.h b/windows/ncurses/include/ncurses/cursesf.h deleted file mode 100644 index 215eb295d..000000000 --- a/windows/ncurses/include/ncurses/cursesf.h +++ /dev/null @@ -1,967 +0,0 @@ -// * This makes emacs happy -*-Mode: C++;-*- -/**************************************************************************** - * Copyright (c) 1998-2004,2005 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Juergen Pfeifer, 1997 * - ****************************************************************************/ - -// $Id: cursesf.h,v 1.28 2005/08/13 18:08:24 tom Exp $ - -#ifndef NCURSES_CURSESF_H_incl -#define NCURSES_CURSESF_H_incl 1 - -#include - -#ifndef __EXT_QNX -#include -#endif - -extern "C" { -# include -} -// -// ------------------------------------------------------------------------- -// The abstract base class for buitin and user defined Fieldtypes. -// ------------------------------------------------------------------------- -// -class NCURSES_IMPEXP NCursesFormField; // forward declaration - -// Class to represent builtin field types as well as C++ written new -// fieldtypes (see classes UserDefineFieldType... -class NCURSES_IMPEXP NCursesFieldType -{ - friend class NCursesFormField; - -protected: - FIELDTYPE* fieldtype; - - inline void OnError(int err) const THROWS(NCursesFormException) { - if (err!=E_OK) - THROW(new NCursesFormException (err)); - } - - NCursesFieldType(FIELDTYPE *f) : fieldtype(f) { - } - - virtual ~NCursesFieldType() {} - - // Set the fields f fieldtype to this one. - virtual void set(NCursesFormField& f) = 0; - -public: - NCursesFieldType() - : fieldtype(STATIC_CAST(FIELDTYPE*)(0)) - { - } - - NCursesFieldType& operator=(const NCursesFieldType& rhs) - { - if (this != &rhs) { - *this = rhs; - } - return *this; - } - - NCursesFieldType(const NCursesFieldType& rhs) - : fieldtype(rhs.fieldtype) - { - } - -}; - -// -// ------------------------------------------------------------------------- -// The class representing a forms field, wrapping the lowlevel FIELD struct -// ------------------------------------------------------------------------- -// -class NCURSES_IMPEXP NCursesFormField -{ - friend class NCursesForm; - -protected: - FIELD *field; // lowlevel structure - NCursesFieldType* ftype; // Associated field type - - // Error handler - inline void OnError (int err) const THROWS(NCursesFormException) { - if (err != E_OK) - THROW(new NCursesFormException (err)); - } - -public: - // Create a 'Null' field. Can be used to delimit a field list - NCursesFormField() - : field(STATIC_CAST(FIELD*)(0)), - ftype(STATIC_CAST(NCursesFieldType*)(0)) - { - } - - // Create a new field - NCursesFormField (int rows, - int ncols, - int first_row = 0, - int first_col = 0, - int offscreen_rows = 0, - int additional_buffers = 0) - : field(0), - ftype(STATIC_CAST(NCursesFieldType*)(0)) - { - field = ::new_field(rows, ncols, first_row, first_col, - offscreen_rows, additional_buffers); - if (!field) - OnError(errno); - } - - NCursesFormField& operator=(const NCursesFormField& rhs) - { - if (this != &rhs) { - *this = rhs; - } - return *this; - } - - NCursesFormField(const NCursesFormField& rhs) - : field(rhs.field), ftype(rhs.ftype) - { - } - - virtual ~NCursesFormField (); - - // Duplicate the field at a new position - inline NCursesFormField* dup(int first_row, int first_col) - { - NCursesFormField* f = new NCursesFormField(); - if (!f) - OnError(E_SYSTEM_ERROR); - else { - f->ftype = ftype; - f->field = ::dup_field(field,first_row,first_col); - if (!f->field) - OnError(errno); - } - return f; - } - - // Link the field to a new location - inline NCursesFormField* link(int first_row, int first_col) { - NCursesFormField* f = new NCursesFormField(); - if (!f) - OnError(E_SYSTEM_ERROR); - else { - f->ftype = ftype; - f->field = ::link_field(field,first_row,first_col); - if (!f->field) - OnError(errno); - } - return f; - } - - // Get the lowlevel field representation - inline FIELD* get_field() const { - return field; - } - - // Retrieve info about the field - inline void info(int& rows, int& ncols, - int& first_row, int& first_col, - int& offscreen_rows, int& additional_buffers) const { - OnError(::field_info(field, &rows, &ncols, - &first_row, &first_col, - &offscreen_rows, &additional_buffers)); - } - - // Retrieve info about the fields dynamic properties. - inline void dynamic_info(int& dynamic_rows, int& dynamic_cols, - int& max_growth) const { - OnError(::dynamic_field_info(field, &dynamic_rows, &dynamic_cols, - &max_growth)); - } - - // For a dynamic field you may set the maximum growth limit. - // A zero means unlimited growth. - inline void set_maximum_growth(int growth = 0) { - OnError(::set_max_field(field,growth)); - } - - // Move the field to a new position - inline void move(int row, int col) { - OnError(::move_field(field,row,col)); - } - - // Mark the field to start a new page - inline void new_page(bool pageFlag = FALSE) { - OnError(::set_new_page(field,pageFlag)); - } - - // Retrieve whether or not the field starts a new page. - inline bool is_new_page() const { - return ::new_page(field); - } - - // Set the justification for the field - inline void set_justification(int just) { - OnError(::set_field_just(field,just)); - } - - // Retrieve the fields justification - inline int justification() const { - return ::field_just(field); - } - // Set the foreground attribute for the field - inline void set_foreground(chtype foreground) { - OnError(::set_field_fore(field,foreground)); - } - - // Retrieve the fields foreground attribute - inline chtype fore() const { - return ::field_fore(field); - } - - // Set the background attribute for the field - inline void set_background(chtype background) { - OnError(::set_field_back(field,background)); - } - - // Retrieve the fields background attribute - inline chtype back() const { - return ::field_back(field); - } - - // Set the padding character for the field - inline void set_pad_character(int padding) { - OnError(::set_field_pad(field, padding)); - } - - // Retrieve the fields padding character - inline int pad() const { - return ::field_pad(field); - } - - // Switch on the fields options - inline void options_on (Field_Options opts) { - OnError (::field_opts_on (field, opts)); - } - - // Switch off the fields options - inline void options_off (Field_Options opts) { - OnError (::field_opts_off (field, opts)); - } - - // Retrieve the fields options - inline Field_Options options () const { - return ::field_opts (field); - } - - // Set the fields options - inline void set_options (Field_Options opts) { - OnError (::set_field_opts (field, opts)); - } - - // Mark the field as changed - inline void set_changed(bool changeFlag = TRUE) { - OnError(::set_field_status(field,changeFlag)); - } - - // Test whether or not the field is marked as changed - inline bool changed() const { - return ::field_status(field); - } - - // Return the index of the field in the field array of a form - // or -1 if the field is not associated to a form - inline int (index)() const { - return ::field_index(field); - } - - // Store a value in a fields buffer. The default buffer is nr. 0 - inline void set_value(const char *val, int buffer = 0) { - OnError(::set_field_buffer(field,buffer,val)); - } - - // Retrieve the value of a fields buffer. The default buffer is nr. 0 - inline char* value(int buffer = 0) const { - return ::field_buffer(field,buffer); - } - - // Set the validation type of the field. - inline void set_fieldtype(NCursesFieldType& f) { - ftype = &f; - f.set(*this); // A good friend may do that... - } - - // Retrieve the validation type of the field. - inline NCursesFieldType* fieldtype() const { - return ftype; - } - -}; - - // This are the built-in hook functions in this C++ binding. In C++ we use - // virtual member functions (see below On_..._Init and On_..._Termination) - // to provide this functionality in an object oriented manner. -extern "C" { - void _nc_xx_frm_init(FORM *); - void _nc_xx_frm_term(FORM *); - void _nc_xx_fld_init(FORM *); - void _nc_xx_fld_term(FORM *); -} - -// -// ------------------------------------------------------------------------- -// The class representing a form, wrapping the lowlevel FORM struct -// ------------------------------------------------------------------------- -// -class NCURSES_IMPEXP NCursesForm : public NCursesPanel -{ -protected: - FORM* form; // the lowlevel structure - -private: - NCursesWindow* sub; // the subwindow object - bool b_sub_owner; // is this our own subwindow? - bool b_framed; // has the form a border? - bool b_autoDelete; // Delete fields when deleting form? - - NCursesFormField** my_fields; // The array of fields for this form - - // This structure is used for the form's user data field to link the - // FORM* to the C++ object and to provide extra space for a user pointer. - typedef struct { - void* m_user; // the pointer for the user's data - const NCursesForm* m_back; // backward pointer to C++ object - const FORM* m_owner; - } UserHook; - - // Get the backward pointer to the C++ object from a FORM - static inline NCursesForm* getHook(const FORM *f) { - UserHook* hook = reinterpret_cast(::form_userptr(f)); - assert(hook != 0 && hook->m_owner==f); - return const_cast(hook->m_back); - } - - friend void _nc_xx_frm_init(FORM *); - friend void _nc_xx_frm_term(FORM *); - friend void _nc_xx_fld_init(FORM *); - friend void _nc_xx_fld_term(FORM *); - - // Calculate FIELD* array for the menu - FIELD** mapFields(NCursesFormField* nfields[]); - -protected: - // internal routines - inline void set_user(void *user) { - UserHook* uptr = reinterpret_cast(::form_userptr (form)); - assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==form); - uptr->m_user = user; - } - - inline void *get_user() { - UserHook* uptr = reinterpret_cast(::form_userptr (form)); - assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==form); - return uptr->m_user; - } - - void InitForm (NCursesFormField* Fields[], - bool with_frame, - bool autoDeleteFields); - - inline void OnError (int err) const THROWS(NCursesFormException) { - if (err != E_OK) - THROW(new NCursesFormException (err)); - } - - // this wraps the form_driver call. - virtual int driver (int c) ; - - // 'Internal' constructor, builds an object without association to a - // field array. - NCursesForm( int nlines, - int ncols, - int begin_y = 0, - int begin_x = 0) - : NCursesPanel(nlines, ncols, begin_y, begin_x), - form (STATIC_CAST(FORM*)(0)), - sub(0), - b_sub_owner(0), - b_framed(0), - b_autoDelete(0), - my_fields(0) - { - } - -public: - // Create form for the default panel. - NCursesForm (NCursesFormField* Fields[], - bool with_frame=FALSE, // reserve space for a frame? - bool autoDelete_Fields=FALSE) // do automatic cleanup? - : NCursesPanel(), - form(0), - sub(0), - b_sub_owner(0), - b_framed(0), - b_autoDelete(0), - my_fields(0) - { - InitForm(Fields, with_frame, autoDelete_Fields); - } - - // Create a form in a panel with the given position and size. - NCursesForm (NCursesFormField* Fields[], - int nlines, - int ncols, - int begin_y, - int begin_x, - bool with_frame=FALSE, // reserve space for a frame? - bool autoDelete_Fields=FALSE) // do automatic cleanup? - : NCursesPanel(nlines, ncols, begin_y, begin_x), - form(0), - sub(0), - b_sub_owner(0), - b_framed(0), - b_autoDelete(0), - my_fields(0) - { - InitForm(Fields, with_frame, autoDelete_Fields); - } - - NCursesForm& operator=(const NCursesForm& rhs) - { - if (this != &rhs) { - *this = rhs; - NCursesPanel::operator=(rhs); - } - return *this; - } - - NCursesForm(const NCursesForm& rhs) - : NCursesPanel(rhs), - form(rhs.form), - sub(rhs.sub), - b_sub_owner(rhs.b_sub_owner), - b_framed(rhs.b_framed), - b_autoDelete(rhs.b_autoDelete), - my_fields(rhs.my_fields) - { - } - - virtual ~NCursesForm(); - - // Set the default attributes for the form - virtual void setDefaultAttributes(); - - // Retrieve current field of the form. - inline NCursesFormField* current_field() const { - return my_fields[::field_index(::current_field(form))]; - } - - // Set the forms subwindow - void setSubWindow(NCursesWindow& sub); - - // Set these fields for the form - inline void setFields(NCursesFormField* Fields[]) { - OnError(::set_form_fields(form,mapFields(Fields))); - } - - // Remove the form from the screen - inline void unpost (void) { - OnError (::unpost_form (form)); - } - - // Post the form to the screen if flag is true, unpost it otherwise - inline void post(bool flag = TRUE) { - OnError (flag ? ::post_form(form) : ::unpost_form (form)); - } - - // Decorations - inline void frame(const char *title=NULL, const char* btitle=NULL) { - if (b_framed) - NCursesPanel::frame(title,btitle); - else - OnError(E_SYSTEM_ERROR); - } - - inline void boldframe(const char *title=NULL, const char* btitle=NULL) { - if (b_framed) - NCursesPanel::boldframe(title,btitle); - else - OnError(E_SYSTEM_ERROR); - } - - inline void label(const char *topLabel, const char *bottomLabel) { - if (b_framed) - NCursesPanel::label(topLabel,bottomLabel); - else - OnError(E_SYSTEM_ERROR); - } - - // ----- - // Hooks - // ----- - - // Called after the form gets repositioned in its window. - // This is especially true if the form is posted. - virtual void On_Form_Init(); - - // Called before the form gets repositioned in its window. - // This is especially true if the form is unposted. - virtual void On_Form_Termination(); - - // Called after the field became the current field - virtual void On_Field_Init(NCursesFormField& field); - - // Called before this field is left as current field. - virtual void On_Field_Termination(NCursesFormField& field); - - // Calculate required window size for the form. - void scale(int& rows, int& ncols) const { - OnError(::scale_form(form,&rows,&ncols)); - } - - // Retrieve number of fields in the form. - int count() const { - return ::field_count(form); - } - - // Make the page the current page of the form. - void set_page(int pageNum) { - OnError(::set_form_page(form, pageNum)); - } - - // Retrieve current page number - int page() const { - return ::form_page(form); - } - - // Switch on the forms options - inline void options_on (Form_Options opts) { - OnError (::form_opts_on (form, opts)); - } - - // Switch off the forms options - inline void options_off (Form_Options opts) { - OnError (::form_opts_off (form, opts)); - } - - // Retrieve the forms options - inline Form_Options options () const { - return ::form_opts (form); - } - - // Set the forms options - inline void set_options (Form_Options opts) { - OnError (::set_form_opts (form, opts)); - } - - // Are there more data in the current field after the data shown - inline bool data_ahead() const { - return ::data_ahead(form); - } - - // Are there more data in the current field before the data shown - inline bool data_behind() const { - return ::data_behind(form); - } - - // Position the cursor to the current field - inline void position_cursor () { - OnError (::pos_form_cursor (form)); - } - // Set the current field - inline void set_current(NCursesFormField& F) { - OnError (::set_current_field(form, F.field)); - } - - // Provide a default key virtualization. Translate the keyboard - // code c into a form request code. - // The default implementation provides a hopefully straightforward - // mapping for the most common keystrokes and form requests. - virtual int virtualize(int c); - - // Operators - inline NCursesFormField* operator[](int i) const { - if ( (i < 0) || (i >= ::field_count (form)) ) - OnError (E_BAD_ARGUMENT); - return my_fields[i]; - } - - // Perform the menu's operation - // Return the field where you left the form. - virtual NCursesFormField* operator()(void); - - // Exception handlers. The default is a Beep. - virtual void On_Request_Denied(int c) const; - virtual void On_Invalid_Field(int c) const; - virtual void On_Unknown_Command(int c) const; - -}; - -// -// ------------------------------------------------------------------------- -// This is the typical C++ typesafe way to allow to attach -// user data to a field of a form. Its assumed that the user -// data belongs to some class T. Use T as template argument -// to create a UserField. -// ------------------------------------------------------------------------- -template class NCURSES_IMPEXP NCursesUserField : public NCursesFormField -{ -public: - NCursesUserField (int rows, - int ncols, - int first_row = 0, - int first_col = 0, - const T* p_UserData = STATIC_CAST(T*)(0), - int offscreen_rows = 0, - int additional_buffers = 0) - : NCursesFormField (rows, ncols, - first_row, first_col, - offscreen_rows, additional_buffers) { - if (field) - OnError(::set_field_userptr(field, STATIC_CAST(void *)(p_UserData))); - } - - virtual ~NCursesUserField() {}; - - inline const T* UserData (void) const { - return reinterpret_cast(::field_userptr (field)); - } - - inline virtual void setUserData(const T* p_UserData) { - if (field) - OnError (::set_field_userptr (field, STATIC_CAST(void *)(p_UserData))); - } -}; -// -// ------------------------------------------------------------------------- -// The same mechanism is used to attach user data to a form -// ------------------------------------------------------------------------- -// -template class NCURSES_IMPEXP NCursesUserForm : public NCursesForm -{ -protected: - // 'Internal' constructor, builds an object without association to a - // field array. - NCursesUserForm( int nlines, - int ncols, - int begin_y = 0, - int begin_x = 0, - const T* p_UserData = STATIC_CAST(T*)(0)) - : NCursesForm(nlines,ncols,begin_y,begin_x) { - if (form) - set_user (const_cast(p_UserData)); - } - -public: - NCursesUserForm (NCursesFormField Fields[], - const T* p_UserData = STATIC_CAST(T*)(0), - bool with_frame=FALSE, - bool autoDelete_Fields=FALSE) - : NCursesForm (Fields, with_frame, autoDelete_Fields) { - if (form) - set_user (const_cast(p_UserData)); - }; - - NCursesUserForm (NCursesFormField Fields[], - int nlines, - int ncols, - int begin_y = 0, - int begin_x = 0, - const T* p_UserData = STATIC_CAST(T*)(0), - bool with_frame=FALSE, - bool autoDelete_Fields=FALSE) - : NCursesForm (Fields, nlines, ncols, begin_y, begin_x, - with_frame, autoDelete_Fields) { - if (form) - set_user (const_cast(p_UserData)); - }; - - virtual ~NCursesUserForm() { - }; - - inline T* UserData (void) const { - return reinterpret_cast(get_user ()); - }; - - inline virtual void setUserData (const T* p_UserData) { - if (form) - set_user (const_cast(p_UserData)); - } - -}; -// -// ------------------------------------------------------------------------- -// Builtin Fieldtypes -// ------------------------------------------------------------------------- -// -class NCURSES_IMPEXP Alpha_Field : public NCursesFieldType -{ -private: - int min_field_width; - - void set(NCursesFormField& f) { - OnError(::set_field_type(f.get_field(),fieldtype,min_field_width)); - } - -public: - Alpha_Field(int width) - : NCursesFieldType(TYPE_ALPHA), - min_field_width(width) { - } -}; - -class NCURSES_IMPEXP Alphanumeric_Field : public NCursesFieldType -{ -private: - int min_field_width; - - void set(NCursesFormField& f) { - OnError(::set_field_type(f.get_field(),fieldtype,min_field_width)); - } - -public: - Alphanumeric_Field(int width) - : NCursesFieldType(TYPE_ALNUM), - min_field_width(width) { - } -}; - -class NCURSES_IMPEXP Integer_Field : public NCursesFieldType -{ -private: - int precision; - long lower_limit, upper_limit; - - void set(NCursesFormField& f) { - OnError(::set_field_type(f.get_field(),fieldtype, - precision,lower_limit,upper_limit)); - } - -public: - Integer_Field(int prec, long low=0L, long high=0L) - : NCursesFieldType(TYPE_INTEGER), - precision(prec), lower_limit(low), upper_limit(high) { - } -}; - -class NCURSES_IMPEXP Numeric_Field : public NCursesFieldType -{ -private: - int precision; - double lower_limit, upper_limit; - - void set(NCursesFormField& f) { - OnError(::set_field_type(f.get_field(),fieldtype, - precision,lower_limit,upper_limit)); - } - -public: - Numeric_Field(int prec, double low=0.0, double high=0.0) - : NCursesFieldType(TYPE_NUMERIC), - precision(prec), lower_limit(low), upper_limit(high) { - } -}; - -class NCURSES_IMPEXP Regular_Expression_Field : public NCursesFieldType -{ -private: - char* regex; - - void set(NCursesFormField& f) { - OnError(::set_field_type(f.get_field(),fieldtype,regex)); - } - - void copy_regex(const char *source) - { - regex = new char[1 + ::strlen(source)]; - (::strcpy)(regex, source); - } - -public: - Regular_Expression_Field(const char *expr) - : NCursesFieldType(TYPE_REGEXP), - regex(NULL) - { - copy_regex(expr); - } - - Regular_Expression_Field& operator=(const Regular_Expression_Field& rhs) - { - if (this != &rhs) { - *this = rhs; - copy_regex(rhs.regex); - NCursesFieldType::operator=(rhs); - } - return *this; - } - - Regular_Expression_Field(const Regular_Expression_Field& rhs) - : NCursesFieldType(rhs), - regex(NULL) - { - copy_regex(rhs.regex); - } - - ~Regular_Expression_Field() { - delete[] regex; - } -}; - -class NCURSES_IMPEXP Enumeration_Field : public NCursesFieldType -{ -private: - const char** list; - int case_sensitive; - int non_unique_matches; - - void set(NCursesFormField& f) { - OnError(::set_field_type(f.get_field(),fieldtype, - list,case_sensitive,non_unique_matches)); - } -public: - Enumeration_Field(const char* enums[], - bool case_sens=FALSE, - bool non_unique=FALSE) - : NCursesFieldType(TYPE_ENUM), - list(enums), - case_sensitive(case_sens ? -1 : 0), - non_unique_matches(non_unique ? -1 : 0) { - } - - Enumeration_Field& operator=(const Enumeration_Field& rhs) - { - if (this != &rhs) { - *this = rhs; - NCursesFieldType::operator=(rhs); - } - return *this; - } - - Enumeration_Field(const Enumeration_Field& rhs) - : NCursesFieldType(rhs), - list(rhs.list), - case_sensitive(rhs.case_sensitive), - non_unique_matches(rhs.non_unique_matches) - { - } -}; - -class NCURSES_IMPEXP IPV4_Address_Field : public NCursesFieldType -{ -private: - void set(NCursesFormField& f) { - OnError(::set_field_type(f.get_field(),fieldtype)); - } - -public: - IPV4_Address_Field() : NCursesFieldType(TYPE_IPV4) { - } -}; - -extern "C" { - bool _nc_xx_fld_fcheck(FIELD *, const void*); - bool _nc_xx_fld_ccheck(int c, const void *); - void* _nc_xx_fld_makearg(va_list*); -} - -// -// ------------------------------------------------------------------------- -// Abstract base class for User-Defined Fieldtypes -// ------------------------------------------------------------------------- -// -class NCURSES_IMPEXP UserDefinedFieldType : public NCursesFieldType -{ - friend class UDF_Init; // Internal helper to set up statics -private: - // For all C++ defined fieldtypes we need only one generic lowlevel - // FIELDTYPE* element. - static FIELDTYPE* generic_fieldtype; - -protected: - // This are the functions required by the low level libforms functions - // to construct a fieldtype. - friend bool _nc_xx_fld_fcheck(FIELD *, const void*); - friend bool _nc_xx_fld_ccheck(int c, const void *); - friend void* _nc_xx_fld_makearg(va_list*); - - void set(NCursesFormField& f) { - OnError(::set_field_type(f.get_field(),fieldtype,&f)); - } - -protected: - // Redefine this function to do a field validation. The argument - // is a reference to the field you should validate. - virtual bool field_check(NCursesFormField& f) = 0; - - // Redefine this function to do a character validation. The argument - // is the character to be validated. - virtual bool char_check (int c) = 0; - -public: - UserDefinedFieldType() : NCursesFieldType(generic_fieldtype) { - } -}; - -extern "C" { - bool _nc_xx_next_choice(FIELD*, const void *); - bool _nc_xx_prev_choice(FIELD*, const void *); -} - -// -// ------------------------------------------------------------------------- -// Abstract base class for User-Defined Fieldtypes with Choice functions -// ------------------------------------------------------------------------- -// -class NCURSES_IMPEXP UserDefinedFieldType_With_Choice : public UserDefinedFieldType -{ - friend class UDF_Init; // Internal helper to set up statics -private: - // For all C++ defined fieldtypes with choice functions we need only one - // generic lowlevel FIELDTYPE* element. - static FIELDTYPE* generic_fieldtype_with_choice; - - // This are the functions required by the low level libforms functions - // to construct a fieldtype with choice functions. - friend bool _nc_xx_next_choice(FIELD*, const void *); - friend bool _nc_xx_prev_choice(FIELD*, const void *); - -protected: - // Redefine this function to do the retrieval of the next choice value. - // The argument is a reference to the field tobe examined. - virtual bool next (NCursesFormField& f) = 0; - - // Redefine this function to do the retrieval of the previous choice value. - // The argument is a reference to the field tobe examined. - virtual bool previous(NCursesFormField& f) = 0; - -public: - UserDefinedFieldType_With_Choice() { - fieldtype = generic_fieldtype_with_choice; - } -}; - -#endif /* NCURSES_CURSESF_H_incl */ diff --git a/windows/ncurses/include/ncurses/cursesm.h b/windows/ncurses/include/ncurses/cursesm.h deleted file mode 100644 index 8e0e2c66c..000000000 --- a/windows/ncurses/include/ncurses/cursesm.h +++ /dev/null @@ -1,672 +0,0 @@ -// * This makes emacs happy -*-Mode: C++;-*- -/**************************************************************************** - * Copyright (c) 1998-2003,2005 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Juergen Pfeifer, 1997 * - ****************************************************************************/ - -// $Id: cursesm.h,v 1.25 2005/08/13 18:10:36 tom Exp $ - -#ifndef NCURSES_CURSESM_H_incl -#define NCURSES_CURSESM_H_incl 1 - -#include - -extern "C" { -# include -} -// -// ------------------------------------------------------------------------- -// This wraps the ITEM type of -// ------------------------------------------------------------------------- -// -class NCURSES_IMPEXP NCursesMenuItem -{ - friend class NCursesMenu; - -protected: - ITEM *item; - - inline void OnError (int err) const THROWS(NCursesMenuException) { - if (err != E_OK) - THROW(new NCursesMenuException (err)); - } - -public: - NCursesMenuItem (const char* p_name = NULL, - const char* p_descript = NULL) - : item(0) - { - item = p_name ? ::new_item (p_name, p_descript) : STATIC_CAST(ITEM*)(0); - if (p_name && !item) - OnError (E_SYSTEM_ERROR); - } - // Create an item. If you pass both parameters as NULL, a delimiting - // item is constructed which can be used to terminate a list of - // NCursesMenu objects. - - NCursesMenuItem& operator=(const NCursesMenuItem& rhs) - { - if (this != &rhs) { - *this = rhs; - } - return *this; - } - - NCursesMenuItem(const NCursesMenuItem& rhs) - : item(0) - { - } - - virtual ~NCursesMenuItem (); - // Release the items memory - - inline const char* name () const { - return ::item_name (item); - } - // Name of the item - - inline const char* description () const { - return ::item_description (item); - } - // Description of the item - - inline int (index) (void) const { - return ::item_index (item); - } - // Index of the item in an item array (or -1) - - inline void options_on (Item_Options opts) { - OnError (::item_opts_on (item, opts)); - } - // Switch on the items options - - inline void options_off (Item_Options opts) { - OnError (::item_opts_off (item, opts)); - } - // Switch off the item's option - - inline Item_Options options () const { - return ::item_opts (item); - } - // Retrieve the items options - - inline void set_options (Item_Options opts) { - OnError (::set_item_opts (item, opts)); - } - // Set the items options - - inline void set_value (bool f) { - OnError (::set_item_value (item,f)); - } - // Set/Reset the items selection state - - inline bool value () const { - return ::item_value (item); - } - // Retrieve the items selection state - - inline bool visible () const { - return ::item_visible (item); - } - // Retrieve visibility of the item - - virtual bool action(); - // Perform an action associated with this item; you may use this in an - // user supplied driver for a menu; you may derive from this class and - // overload action() to supply items with different actions. - // If an action returns true, the menu will be exited. The default action - // is to do nothing. -}; - -// Prototype for an items callback function. -typedef bool ITEMCALLBACK(NCursesMenuItem&); - -// If you don't like to create a child class for individual items to -// overload action(), you may use this class and provide a callback -// function pointer for items. -class NCURSES_IMPEXP NCursesMenuCallbackItem : public NCursesMenuItem -{ -private: - ITEMCALLBACK* p_fct; - -public: - NCursesMenuCallbackItem(ITEMCALLBACK* fct = NULL, - const char* p_name = NULL, - const char* p_descript = NULL ) - : NCursesMenuItem (p_name, p_descript), - p_fct (fct) { - } - - NCursesMenuCallbackItem& operator=(const NCursesMenuCallbackItem& rhs) - { - if (this != &rhs) { - *this = rhs; - } - return *this; - } - - NCursesMenuCallbackItem(const NCursesMenuCallbackItem& rhs) - : NCursesMenuItem(rhs), - p_fct(0) - { - } - - virtual ~NCursesMenuCallbackItem(); - - bool action(); -}; - - // This are the built-in hook functions in this C++ binding. In C++ we use - // virtual member functions (see below On_..._Init and On_..._Termination) - // to provide this functionality in an object oriented manner. -extern "C" { - void _nc_xx_mnu_init(MENU *); - void _nc_xx_mnu_term(MENU *); - void _nc_xx_itm_init(MENU *); - void _nc_xx_itm_term(MENU *); -} - -// -// ------------------------------------------------------------------------- -// This wraps the MENU type of -// ------------------------------------------------------------------------- -// -class NCURSES_IMPEXP NCursesMenu : public NCursesPanel -{ -protected: - MENU *menu; - -private: - NCursesWindow* sub; // the subwindow object - bool b_sub_owner; // is this our own subwindow? - bool b_framed; // has the menu a border? - bool b_autoDelete; // Delete items when deleting menu? - - NCursesMenuItem** my_items; // The array of items for this menu - - // This structure is used for the menu's user data field to link the - // MENU* to the C++ object and to provide extra space for a user pointer. - typedef struct { - void* m_user; // the pointer for the user's data - const NCursesMenu* m_back; // backward pointer to C++ object - const MENU* m_owner; - } UserHook; - - // Get the backward pointer to the C++ object from a MENU - static inline NCursesMenu* getHook(const MENU *m) { - UserHook* hook = STATIC_CAST(UserHook*)(::menu_userptr(m)); - assert(hook != 0 && hook->m_owner==m); - return const_cast(hook->m_back); - } - - friend void _nc_xx_mnu_init(MENU *); - friend void _nc_xx_mnu_term(MENU *); - friend void _nc_xx_itm_init(MENU *); - friend void _nc_xx_itm_term(MENU *); - - // Calculate ITEM* array for the menu - ITEM** mapItems(NCursesMenuItem* nitems[]); - -protected: - // internal routines - inline void set_user(void *user) { - UserHook* uptr = STATIC_CAST(UserHook*)(::menu_userptr (menu)); - assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==menu); - uptr->m_user = user; - } - - inline void *get_user() { - UserHook* uptr = STATIC_CAST(UserHook*)(::menu_userptr (menu)); - assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==menu); - return uptr->m_user; - } - - void InitMenu (NCursesMenuItem* menu[], - bool with_frame, - bool autoDeleteItems); - - inline void OnError (int err) const THROWS(NCursesMenuException) { - if (err != E_OK) - THROW(new NCursesMenuException (this, err)); - } - - // this wraps the menu_driver call. - virtual int driver (int c) ; - - // 'Internal' constructor to create a menu without association to - // an array of items. - NCursesMenu( int nlines, - int ncols, - int begin_y = 0, - int begin_x = 0) - : NCursesPanel(nlines,ncols,begin_y,begin_x), - menu (STATIC_CAST(MENU*)(0)), - sub(0), - b_sub_owner(0), - b_framed(0), - b_autoDelete(0), - my_items(0) - { - } - -public: - // Make a full window size menu - NCursesMenu (NCursesMenuItem* Items[], - bool with_frame=FALSE, // Reserve space for a frame? - bool autoDelete_Items=FALSE) // Autocleanup of Items? - : NCursesPanel(), - menu(0), - sub(0), - b_sub_owner(0), - b_framed(0), - b_autoDelete(0), - my_items(0) - { - InitMenu(Items, with_frame, autoDelete_Items); - } - - // Make a menu with a window of this size. - NCursesMenu (NCursesMenuItem* Items[], - int nlines, - int ncols, - int begin_y = 0, - int begin_x = 0, - bool with_frame=FALSE, // Reserve space for a frame? - bool autoDelete_Items=FALSE) // Autocleanup of Items? - : NCursesPanel(nlines, ncols, begin_y, begin_x), - menu(0), - sub(0), - b_sub_owner(0), - b_framed(0), - b_autoDelete(0), - my_items(0) - { - InitMenu(Items, with_frame, autoDelete_Items); - } - - NCursesMenu& operator=(const NCursesMenu& rhs) - { - if (this != &rhs) { - *this = rhs; - NCursesPanel::operator=(rhs); - } - return *this; - } - - NCursesMenu(const NCursesMenu& rhs) - : NCursesPanel(rhs), - menu(rhs.menu), - sub(rhs.sub), - b_sub_owner(rhs.b_sub_owner), - b_framed(rhs.b_framed), - b_autoDelete(rhs.b_autoDelete), - my_items(rhs.my_items) - { - } - - virtual ~NCursesMenu (); - - // Retrieve the menus subwindow - inline NCursesWindow& subWindow() const { - assert(sub!=NULL); - return *sub; - } - - // Set the menus subwindow - void setSubWindow(NCursesWindow& sub); - - // Set these items for the menu - inline void setItems(NCursesMenuItem* Items[]) { - OnError(::set_menu_items(menu,mapItems(Items))); - } - - // Remove the menu from the screen - inline void unpost (void) { - OnError (::unpost_menu (menu)); - } - - // Post the menu to the screen if flag is true, unpost it otherwise - inline void post(bool flag = TRUE) { - flag ? OnError (::post_menu(menu)) : OnError (::unpost_menu (menu)); - } - - // Get the numer of rows and columns for this menu - inline void scale (int& mrows, int& mcols) const { - OnError (::scale_menu (menu, &mrows, &mcols)); - } - - // Set the format of this menu - inline void set_format(int mrows, int mcols) { - OnError (::set_menu_format(menu, mrows, mcols)); - } - - // Get the format of this menu - inline void menu_format(int& rows,int& ncols) { - ::menu_format(menu,&rows,&ncols); - } - - // Items of the menu - inline NCursesMenuItem* items() const { - return *my_items; - } - - // Get the number of items in this menu - inline int count() const { - return ::item_count(menu); - } - - // Get the current item (i.e. the one the cursor is located) - inline NCursesMenuItem* current_item() const { - return my_items[::item_index(::current_item(menu))]; - } - - // Get the marker string - inline const char* mark() const { - return ::menu_mark(menu); - } - - // Set the marker string - inline void set_mark(const char *marker) { - OnError (::set_menu_mark (menu, marker)); - } - - // Get the name of the request code c - inline static const char* request_name(int c) { - return ::menu_request_name(c); - } - - // Get the current pattern - inline char* pattern() const { - return ::menu_pattern(menu); - } - - // true if there is a pattern match, false otherwise. - bool set_pattern (const char *pat); - - // set the default attributes for the menu - // i.e. set fore, back and grey attribute - virtual void setDefaultAttributes(); - - // Get the menus background attributes - inline chtype back() const { - return ::menu_back(menu); - } - - // Get the menus foreground attributes - inline chtype fore() const { - return ::menu_fore(menu); - } - - // Get the menus grey attributes (used for unselectable items) - inline chtype grey() const { - return ::menu_grey(menu); - } - - // Set the menus background attributes - inline chtype set_background(chtype a) { - return ::set_menu_back(menu,a); - } - - // Set the menus foreground attributes - inline chtype set_foreground(chtype a) { - return ::set_menu_fore(menu,a); - } - - // Set the menus grey attributes (used for unselectable items) - inline chtype set_grey(chtype a) { - return ::set_menu_grey(menu,a); - } - - inline void options_on (Menu_Options opts) { - OnError (::menu_opts_on (menu,opts)); - } - - inline void options_off(Menu_Options opts) { - OnError (::menu_opts_off(menu,opts)); - } - - inline Menu_Options options() const { - return ::menu_opts(menu); - } - - inline void set_options (Menu_Options opts) { - OnError (::set_menu_opts (menu,opts)); - } - - inline int pad() const { - return ::menu_pad(menu); - } - - inline void set_pad (int padch) { - OnError (::set_menu_pad (menu, padch)); - } - - // Position the cursor to the current item - inline void position_cursor () const { - OnError (::pos_menu_cursor (menu)); - } - - // Set the current item - inline void set_current(NCursesMenuItem& I) { - OnError (::set_current_item(menu, I.item)); - } - - // Get the current top row of the menu - inline int top_row (void) const { - return ::top_row (menu); - } - - // Set the current top row of the menu - inline void set_top_row (int row) { - OnError (::set_top_row (menu, row)); - } - - // spacing control - // Set the spacing for the menu - inline void setSpacing(int spc_description, - int spc_rows, - int spc_columns) { - OnError(::set_menu_spacing(menu, - spc_description, - spc_rows, - spc_columns)); - } - - // Get the spacing info for the menu - inline void Spacing(int& spc_description, - int& spc_rows, - int& spc_columns) const { - OnError(::menu_spacing(menu, - &spc_description, - &spc_rows, - &spc_columns)); - } - - // Decorations - inline void frame(const char *title=NULL, const char* btitle=NULL) { - if (b_framed) - NCursesPanel::frame(title,btitle); - else - OnError(E_SYSTEM_ERROR); - } - - inline void boldframe(const char *title=NULL, const char* btitle=NULL) { - if (b_framed) - NCursesPanel::boldframe(title,btitle); - else - OnError(E_SYSTEM_ERROR); - } - - inline void label(const char *topLabel, const char *bottomLabel) { - if (b_framed) - NCursesPanel::label(topLabel,bottomLabel); - else - OnError(E_SYSTEM_ERROR); - } - - // ----- - // Hooks - // ----- - - // Called after the menu gets repositioned in its window. - // This is especially true if the menu is posted. - virtual void On_Menu_Init(); - - // Called before the menu gets repositioned in its window. - // This is especially true if the menu is unposted. - virtual void On_Menu_Termination(); - - // Called after the item became the current item - virtual void On_Item_Init(NCursesMenuItem& item); - - // Called before this item is left as current item. - virtual void On_Item_Termination(NCursesMenuItem& item); - - // Provide a default key virtualization. Translate the keyboard - // code c into a menu request code. - // The default implementation provides a hopefully straightforward - // mapping for the most common keystrokes and menu requests. - virtual int virtualize(int c); - - - // Operators - inline NCursesMenuItem* operator[](int i) const { - if ( (i < 0) || (i >= ::item_count (menu)) ) - OnError (E_BAD_ARGUMENT); - return (my_items[i]); - } - - // Perform the menu's operation - // Return the item where you left the selection mark for a single - // selection menu, or NULL for a multivalued menu. - virtual NCursesMenuItem* operator()(void); - - // -------------------- - // Exception handlers - // Called by operator() - // -------------------- - - // Called if the request is denied - virtual void On_Request_Denied(int c) const; - - // Called if the item is not selectable - virtual void On_Not_Selectable(int c) const; - - // Called if pattern doesn't match - virtual void On_No_Match(int c) const; - - // Called if the command is unknown - virtual void On_Unknown_Command(int c) const; - -}; -// -// ------------------------------------------------------------------------- -// This is the typical C++ typesafe way to allow to attach -// user data to an item of a menu. Its assumed that the user -// data belongs to some class T. Use T as template argument -// to create a UserItem. -// ------------------------------------------------------------------------- -// -template class NCURSES_IMPEXP NCursesUserItem : public NCursesMenuItem -{ -public: - NCursesUserItem (const char* p_name, - const char* p_descript = NULL, - const T* p_UserData = STATIC_CAST(T*)(0)) - : NCursesMenuItem (p_name, p_descript) { - if (item) - OnError (::set_item_userptr (item, const_cast(reinterpret_cast(p_UserData)))); - } - - virtual ~NCursesUserItem() {} - - inline const T* UserData (void) const { - return reinterpret_cast(::item_userptr (item)); - }; - - inline virtual void setUserData(const T* p_UserData) { - if (item) - OnError (::set_item_userptr (item, const_cast(reinterpret_cast(p_UserData)))); - } -}; -// -// ------------------------------------------------------------------------- -// The same mechanism is used to attach user data to a menu -// ------------------------------------------------------------------------- -// -template class NCURSES_IMPEXP NCursesUserMenu : public NCursesMenu -{ -protected: - NCursesUserMenu( int nlines, - int ncols, - int begin_y = 0, - int begin_x = 0, - const T* p_UserData = STATIC_CAST(T*)(0)) - : NCursesMenu(nlines,ncols,begin_y,begin_x) { - if (menu) - set_user (const_cast(p_UserData)); - } - -public: - NCursesUserMenu (NCursesMenuItem Items[], - const T* p_UserData = STATIC_CAST(T*)(0), - bool with_frame=FALSE, - bool autoDelete_Items=FALSE) - : NCursesMenu (Items, with_frame, autoDelete_Items) { - if (menu) - set_user (const_cast(p_UserData)); - }; - - NCursesUserMenu (NCursesMenuItem Items[], - int nlines, - int ncols, - int begin_y = 0, - int begin_x = 0, - const T* p_UserData = STATIC_CAST(T*)(0), - bool with_frame=FALSE) - : NCursesMenu (Items, nlines, ncols, begin_y, begin_x, with_frame) { - if (menu) - set_user (const_cast(p_UserData)); - }; - - virtual ~NCursesUserMenu() { - }; - - inline T* UserData (void) const { - return reinterpret_cast(get_user ()); - }; - - inline virtual void setUserData (const T* p_UserData) { - if (menu) - set_user (const_cast(p_UserData)); - } -}; - -#endif /* NCURSES_CURSESM_H_incl */ diff --git a/windows/ncurses/include/ncurses/cursesp.h b/windows/ncurses/include/ncurses/cursesp.h deleted file mode 100644 index 720f999d0..000000000 --- a/windows/ncurses/include/ncurses/cursesp.h +++ /dev/null @@ -1,268 +0,0 @@ -// * This makes emacs happy -*-Mode: C++;-*- -/**************************************************************************** - * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Juergen Pfeifer, 1997 * - ****************************************************************************/ - -#ifndef NCURSES_CURSESP_H_incl -#define NCURSES_CURSESP_H_incl 1 - -// $Id: cursesp.h,v 1.29 2008/08/16 17:20:23 tom Exp $ - -#include - -extern "C" { -# include -} - -class NCURSES_IMPEXP NCursesPanel - : public NCursesWindow -{ -protected: - PANEL *p; - static NCursesPanel *dummy; - -private: - // This structure is used for the panel's user data field to link the - // PANEL* to the C++ object and to provide extra space for a user pointer. - typedef struct { - void* m_user; // the pointer for the user's data - const NCursesPanel* m_back; // backward pointer to C++ object - const PANEL* m_owner; // the panel itself - } UserHook; - - inline UserHook *UserPointer() - { - UserHook* uptr = reinterpret_cast( - const_cast(::panel_userptr (p))); - return uptr; - } - - void init(); // Initialize the panel object - -protected: - void set_user(void *user) - { - UserHook* uptr = UserPointer(); - if (uptr != 0 && uptr->m_back==this && uptr->m_owner==p) { - uptr->m_user = user; - } - } - // Set the user pointer of the panel. - - void *get_user() - { - UserHook* uptr = UserPointer(); - void *result = 0; - if (uptr != 0 && uptr->m_back==this && uptr->m_owner==p) - result = uptr->m_user; - return result; - } - - void OnError (int err) const THROWS(NCursesPanelException) - { - if (err==ERR) - THROW(new NCursesPanelException (this, err)); - } - // If err is equal to the curses error indicator ERR, an error handler - // is called. - - // Get a keystroke. Default implementation calls getch() - virtual int getKey(void); - -public: - NCursesPanel(int nlines, - int ncols, - int begin_y = 0, - int begin_x = 0) - : NCursesWindow(nlines,ncols,begin_y,begin_x), p(0) - { - init(); - } - // Create a panel with this size starting at the requested position. - - NCursesPanel() - : NCursesWindow(::stdscr), p(0) - { - init(); - } - // This constructor creates the default Panel associated with the - // ::stdscr window - - NCursesPanel& operator=(const NCursesPanel& rhs) - { - if (this != &rhs) { - *this = rhs; - NCursesWindow::operator=(rhs); - } - return *this; - } - - NCursesPanel(const NCursesPanel& rhs) - : NCursesWindow(rhs), - p(rhs.p) - { - } - - virtual ~NCursesPanel(); - - // basic manipulation - inline void hide() - { - OnError (::hide_panel(p)); - } - // Hide the panel. It stays in the stack but becomes invisible. - - inline void show() - { - OnError (::show_panel(p)); - } - // Show the panel, i.e. make it visible. - - inline void top() - { - OnError (::top_panel(p)); - } - // Make this panel the top panel in the stack. - - inline void bottom() - { - OnError (::bottom_panel(p)); - } - // Make this panel the bottom panel in the stack. - // N.B.: The panel associated with ::stdscr is always on the bottom. So - // actually bottom() makes the panel the first above ::stdscr. - - virtual int mvwin(int y, int x) - { - OnError(::move_panel(p, y, x)); - return OK; - } - - inline bool hidden() const - { - return (::panel_hidden (p) ? TRUE : FALSE); - } - // Return TRUE if the panel is hidden, FALSE otherwise. - -/* The functions panel_above() and panel_below() are not reflected in - the NCursesPanel class. The reason for this is, that we cannot - assume that a panel retrieved by those operations is one wrapped - by a C++ class. Although this situation might be handled, we also - need a reverse mapping from PANEL to NCursesPanel which needs some - redesign of the low level stuff. At the moment, we define them in the - interface but they will always produce an error. */ - inline NCursesPanel& above() const - { - OnError(ERR); - return *dummy; - } - - inline NCursesPanel& below() const - { - OnError(ERR); - return *dummy; - } - - // Those two are rewrites of the corresponding virtual members of - // NCursesWindow - virtual int refresh(); - // Propagate all panel changes to the virtual screen and update the - // physical screen. - - virtual int noutrefresh(); - // Propagate all panel changes to the virtual screen. - - static void redraw(); - // Redraw all panels. - - // decorations - virtual void frame(const char* title=NULL, - const char* btitle=NULL); - // Put a frame around the panel and put the title centered in the top line - // and btitle in the bottom line. - - virtual void boldframe(const char* title=NULL, - const char* btitle=NULL); - // Same as frame(), but use highlighted attributes. - - virtual void label(const char* topLabel, - const char* bottomLabel); - // Put the title centered in the top line and btitle in the bottom line. - - virtual void centertext(int row,const char* label); - // Put the label text centered in the specified row. -}; - -/* We use templates to provide a typesafe mechanism to associate - * user data with a panel. A NCursesUserPanel is a panel - * associated with some user data of type T. - */ -template class NCursesUserPanel : public NCursesPanel -{ -public: - NCursesUserPanel (int nlines, - int ncols, - int begin_y = 0, - int begin_x = 0, - const T* p_UserData = STATIC_CAST(T*)(0)) - : NCursesPanel (nlines, ncols, begin_y, begin_x) - { - if (p) - set_user (const_cast(p_UserData)); - }; - // This creates an user panel of the requested size with associated - // user data pointed to by p_UserData. - - NCursesUserPanel(const T* p_UserData = STATIC_CAST(T*)(0)) : NCursesPanel() - { - if (p) - set_user(const_cast(p_UserData)); - }; - // This creates an user panel associated with the ::stdscr and user data - // pointed to by p_UserData. - - virtual ~NCursesUserPanel() {}; - - T* UserData (void) const - { - return reinterpret_cast(get_user ()); - }; - // Retrieve the user data associated with the panel. - - virtual void setUserData (const T* p_UserData) - { - if (p) - set_user (const_cast(p_UserData)); - } - // Associate the user panel with the user data pointed to by p_UserData. -}; - -#endif /* NCURSES_CURSESP_H_incl */ diff --git a/windows/ncurses/include/ncurses/cursesw.h b/windows/ncurses/include/ncurses/cursesw.h deleted file mode 100644 index 95659f2fd..000000000 --- a/windows/ncurses/include/ncurses/cursesw.h +++ /dev/null @@ -1,1556 +0,0 @@ -// * This makes emacs happy -*-Mode: C++;-*- -// vile:cppmode -/**************************************************************************** - * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -#ifndef NCURSES_CURSESW_H_incl -#define NCURSES_CURSESW_H_incl 1 - -// $Id: cursesw.h,v 1.48 2008/01/19 21:09:10 tom Exp $ - -#include - -extern "C" { -# include -} - -/* SCO 3.2v4 curses.h includes term.h, which defines lines as a macro. - Undefine it here, because NCursesWindow uses lines as a method. */ -#undef lines - -/* "Convert" macros to inlines. We'll define it as another symbol to avoid - * conflict with library symbols. - */ -#undef UNDEF -#define UNDEF(name) CUR_ ##name - -#ifdef addch -inline int UNDEF(addch)(chtype ch) { return addch(ch); } -#undef addch -#define addch UNDEF(addch) -#endif - -#ifdef addchstr -inline int UNDEF(addchstr)(chtype *at) { return addchstr(at); } -#undef addchstr -#define addchstr UNDEF(addchstr) -#endif - -#ifdef addnstr -inline int UNDEF(addnstr)(const char *str, int n) -{ return addnstr(str, n); } -#undef addnstr -#define addnstr UNDEF(addnstr) -#endif - -#ifdef addstr -inline int UNDEF(addstr)(const char * str) { return addstr(str); } -#undef addstr -#define addstr UNDEF(addstr) -#endif - -#ifdef attroff -inline int UNDEF(attroff)(chtype at) { return attroff(at); } -#undef attroff -#define attroff UNDEF(attroff) -#endif - -#ifdef attron -inline int UNDEF(attron)(chtype at) { return attron(at); } -#undef attron -#define attron UNDEF(attron) -#endif - -#ifdef attrset -inline chtype UNDEF(attrset)(chtype at) { return attrset(at); } -#undef attrset -#define attrset UNDEF(attrset) -#endif - -#ifdef bkgd -inline int UNDEF(bkgd)(chtype ch) { return bkgd(ch); } -#undef bkgd -#define bkgd UNDEF(bkgd) -#endif - -#ifdef bkgdset -inline void UNDEF(bkgdset)(chtype ch) { bkgdset(ch); } -#undef bkgdset -#define bkgdset UNDEF(bkgdset) -#endif - -#ifdef border -inline int UNDEF(border)(chtype ls, chtype rs, chtype ts, chtype bs, chtype tl, chtype tr, chtype bl, chtype br) -{ return border(ls, rs, ts, bs, tl, tr, bl, br); } -#undef border -#define border UNDEF(border) -#endif - -#ifdef box -inline int UNDEF(box)(WINDOW *win, int v, int h) { return box(win, v, h); } -#undef box -#define box UNDEF(box) -#endif - -#ifdef chgat -inline int UNDEF(chgat)(int n, attr_t attr, short color, const void *opts) { - return chgat(n, attr, color, opts); } -#undef chgat -#define chgat UNDEF(chgat) -#endif - -#ifdef clear -inline int UNDEF(clear)() { return clear(); } -#undef clear -#define clear UNDEF(clear) -#endif - -#ifdef clearok -inline int UNDEF(clearok)(WINDOW* win, bool bf) { return clearok(win, bf); } -#undef clearok -#define clearok UNDEF(clearok) -#else -extern "C" NCURSES_IMPEXP int NCURSES_API clearok(WINDOW*, bool); -#endif - -#ifdef clrtobot -inline int UNDEF(clrtobot)() { return clrtobot(); } -#undef clrtobot -#define clrtobot UNDEF(clrtobot) -#endif - -#ifdef clrtoeol -inline int UNDEF(clrtoeol)() { return clrtoeol(); } -#undef clrtoeol -#define clrtoeol UNDEF(clrtoeol) -#endif - -#ifdef color_set -inline chtype UNDEF(color_set)(short p, void* opts) { return color_set(p, opts); } -#undef color_set -#define color_set UNDEF(color_set) -#endif - -#ifdef crmode -inline int UNDEF(crmode)(void) { return crmode(); } -#undef crmode -#define crmode UNDEF(crmode) -#endif - -#ifdef delch -inline int UNDEF(delch)() { return delch(); } -#undef delch -#define delch UNDEF(delch) -#endif - -#ifdef deleteln -inline int UNDEF(deleteln)() { return deleteln(); } -#undef deleteln -#define deleteln UNDEF(deleteln) -#endif - -#ifdef echochar -inline int UNDEF(echochar)(chtype ch) { return echochar(ch); } -#undef echochar -#define echochar UNDEF(echochar) -#endif - -#ifdef erase -inline int UNDEF(erase)() { return erase(); } -#undef erase -#define erase UNDEF(erase) -#endif - -#ifdef fixterm -inline int UNDEF(fixterm)(void) { return fixterm(); } -#undef fixterm -#define fixterm UNDEF(fixterm) -#endif - -#ifdef flushok -inline int UNDEF(flushok)(WINDOW* _win, bool _bf) { - return flushok(_win, _bf); } -#undef flushok -#define flushok UNDEF(flushok) -#else -#define _no_flushok -#endif - -#ifdef getattrs -inline int UNDEF(getattrs)(WINDOW *win) { return getattrs(win); } -#undef getattrs -#define getattrs UNDEF(getattrs) -#endif - -#ifdef getbegyx -inline void UNDEF(getbegyx)(WINDOW* win, int& y, int& x) { getbegyx(win, y, x); } -#undef getbegyx -#define getbegyx UNDEF(getbegyx) -#endif - -#ifdef getbkgd -inline chtype UNDEF(getbkgd)(const WINDOW *win) { return getbkgd(win); } -#undef getbkgd -#define getbkgd UNDEF(getbkgd) -#endif - -#ifdef getch -inline int UNDEF(getch)() { return getch(); } -#undef getch -#define getch UNDEF(getch) -#endif - -#ifdef getmaxyx -inline void UNDEF(getmaxyx)(WINDOW* win, int& y, int& x) { getmaxyx(win, y, x); } -#undef getmaxyx -#define getmaxyx UNDEF(getmaxyx) -#endif - -#ifdef getnstr -inline int UNDEF(getnstr)(char *_str, int n) { return getnstr(_str, n); } -#undef getnstr -#define getnstr UNDEF(getnstr) -#endif - -#ifdef getparyx -inline void UNDEF(getparyx)(WINDOW* win, int& y, int& x) { getparyx(win, y, x); } -#undef getparyx -#define getparyx UNDEF(getparyx) -#endif - -#ifdef getstr -inline int UNDEF(getstr)(char *_str) { return getstr(_str); } -#undef getstr -#define getstr UNDEF(getstr) -#endif - -#ifdef getyx -inline void UNDEF(getyx)(const WINDOW* win, int& y, int& x) { - getyx(win, y, x); } -#undef getyx -#define getyx UNDEF(getyx) -#endif - -#ifdef hline -inline int UNDEF(hline)(chtype ch, int n) { return hline(ch, n); } -#undef hline -#define hline UNDEF(hline) -#endif - -#ifdef inch -inline chtype UNDEF(inch)() { return inch(); } -#undef inch -#define inch UNDEF(inch) -#endif - -#ifdef inchstr -inline int UNDEF(inchstr)(chtype *str) { return inchstr(str); } -#undef inchstr -#define inchstr UNDEF(inchstr) -#endif - -#ifdef innstr -inline int UNDEF(innstr)(char *_str, int n) { return innstr(_str, n); } -#undef innstr -#define innstr UNDEF(innstr) -#endif - -#ifdef insch -inline int UNDEF(insch)(chtype c) { return insch(c); } -#undef insch -#define insch UNDEF(insch) -#endif - -#ifdef insdelln -inline int UNDEF(insdelln)(int n) { return insdelln(n); } -#undef insdelln -#define insdelln UNDEF(insdelln) -#endif - -#ifdef insertln -inline int UNDEF(insertln)() { return insertln(); } -#undef insertln -#define insertln UNDEF(insertln) -#endif - -#ifdef insnstr -inline int UNDEF(insnstr)(const char *_str, int n) { - return insnstr(_str, n); } -#undef insnstr -#define insnstr UNDEF(insnstr) -#endif - -#ifdef insstr -inline int UNDEF(insstr)(const char *_str) { - return insstr(_str); } -#undef insstr -#define insstr UNDEF(insstr) -#endif - -#ifdef instr -inline int UNDEF(instr)(char *_str) { return instr(_str); } -#undef instr -#define instr UNDEF(instr) -#endif - -#ifdef intrflush -inline void UNDEF(intrflush)(WINDOW *win, bool bf) { intrflush(); } -#undef intrflush -#define intrflush UNDEF(intrflush) -#endif - -#ifdef leaveok -inline int UNDEF(leaveok)(WINDOW* win, bool bf) { return leaveok(win, bf); } -#undef leaveok -#define leaveok UNDEF(leaveok) -#else -extern "C" NCURSES_IMPEXP int NCURSES_API leaveok(WINDOW* win, bool bf); -#endif - -#ifdef move -inline int UNDEF(move)(int x, int y) { return move(x, y); } -#undef move -#define move UNDEF(move) -#endif - -#ifdef mvaddch -inline int UNDEF(mvaddch)(int y, int x, chtype ch) -{ return mvaddch(y, x, ch); } -#undef mvaddch -#define mvaddch UNDEF(mvaddch) -#endif - -#ifdef mvaddnstr -inline int UNDEF(mvaddnstr)(int y, int x, const char *str, int n) -{ return mvaddnstr(y, x, str, n); } -#undef mvaddnstr -#define mvaddnstr UNDEF(mvaddnstr) -#endif - -#ifdef mvaddstr -inline int UNDEF(mvaddstr)(int y, int x, const char * str) -{ return mvaddstr(y, x, str); } -#undef mvaddstr -#define mvaddstr UNDEF(mvaddstr) -#endif - -#ifdef mvchgat -inline int UNDEF(mvchgat)(int y, int x, int n, - attr_t attr, short color, const void *opts) { - return mvchgat(y, x, n, attr, color, opts); } -#undef mvchgat -#define mvchgat UNDEF(mvchgat) -#endif - -#ifdef mvdelch -inline int UNDEF(mvdelch)(int y, int x) { return mvdelch(y, x);} -#undef mvdelch -#define mvdelch UNDEF(mvdelch) -#endif - -#ifdef mvgetch -inline int UNDEF(mvgetch)(int y, int x) { return mvgetch(y, x);} -#undef mvgetch -#define mvgetch UNDEF(mvgetch) -#endif - -#ifdef mvgetnstr -inline int UNDEF(mvgetnstr)(int y, int x, char *str, int n) { - return mvgetnstr(y, x, str, n);} -#undef mvgetnstr -#define mvgetnstr UNDEF(mvgetnstr) -#endif - -#ifdef mvgetstr -inline int UNDEF(mvgetstr)(int y, int x, char *str) {return mvgetstr(y, x, str);} -#undef mvgetstr -#define mvgetstr UNDEF(mvgetstr) -#endif - -#ifdef mvinch -inline chtype UNDEF(mvinch)(int y, int x) { return mvinch(y, x);} -#undef mvinch -#define mvinch UNDEF(mvinch) -#endif - -#ifdef mvinnstr -inline int UNDEF(mvinnstr)(int y, int x, char *_str, int n) { - return mvinnstr(y, x, _str, n); } -#undef mvinnstr -#define mvinnstr UNDEF(mvinnstr) -#endif - -#ifdef mvinsch -inline int UNDEF(mvinsch)(int y, int x, chtype c) -{ return mvinsch(y, x, c); } -#undef mvinsch -#define mvinsch UNDEF(mvinsch) -#endif - -#ifdef mvinsnstr -inline int UNDEF(mvinsnstr)(int y, int x, const char *_str, int n) { - return mvinsnstr(y, x, _str, n); } -#undef mvinsnstr -#define mvinsnstr UNDEF(mvinsnstr) -#endif - -#ifdef mvinsstr -inline int UNDEF(mvinsstr)(int y, int x, const char *_str) { - return mvinsstr(y, x, _str); } -#undef mvinsstr -#define mvinsstr UNDEF(mvinsstr) -#endif - -#ifdef mvwaddch -inline int UNDEF(mvwaddch)(WINDOW *win, int y, int x, const chtype ch) -{ return mvwaddch(win, y, x, ch); } -#undef mvwaddch -#define mvwaddch UNDEF(mvwaddch) -#endif - -#ifdef mvwaddchnstr -inline int UNDEF(mvwaddchnstr)(WINDOW *win, int y, int x, const chtype *str, int n) -{ return mvwaddchnstr(win, y, x, str, n); } -#undef mvwaddchnstr -#define mvwaddchnstr UNDEF(mvwaddchnstr) -#endif - -#ifdef mvwaddchstr -inline int UNDEF(mvwaddchstr)(WINDOW *win, int y, int x, const chtype *str) -{ return mvwaddchstr(win, y, x, str); } -#undef mvwaddchstr -#define mvwaddchstr UNDEF(mvwaddchstr) -#endif - -#ifdef mvwaddnstr -inline int UNDEF(mvwaddnstr)(WINDOW *win, int y, int x, const char *str, int n) -{ return mvwaddnstr(win, y, x, str, n); } -#undef mvwaddnstr -#define mvwaddnstr UNDEF(mvwaddnstr) -#endif - -#ifdef mvwaddstr -inline int UNDEF(mvwaddstr)(WINDOW *win, int y, int x, const char * str) -{ return mvwaddstr(win, y, x, str); } -#undef mvwaddstr -#define mvwaddstr UNDEF(mvwaddstr) -#endif - -#ifdef mvwchgat -inline int UNDEF(mvwchgat)(WINDOW *win, int y, int x, int n, - attr_t attr, short color, const void *opts) { - return mvwchgat(win, y, x, n, attr, color, opts); } -#undef mvwchgat -#define mvwchgat UNDEF(mvwchgat) -#endif - -#ifdef mvwdelch -inline int UNDEF(mvwdelch)(WINDOW *win, int y, int x) -{ return mvwdelch(win, y, x); } -#undef mvwdelch -#define mvwdelch UNDEF(mvwdelch) -#endif - -#ifdef mvwgetch -inline int UNDEF(mvwgetch)(WINDOW *win, int y, int x) { return mvwgetch(win, y, x);} -#undef mvwgetch -#define mvwgetch UNDEF(mvwgetch) -#endif - -#ifdef mvwgetnstr -inline int UNDEF(mvwgetnstr)(WINDOW *win, int y, int x, char *str, int n) -{return mvwgetnstr(win, y, x, str, n);} -#undef mvwgetnstr -#define mvwgetnstr UNDEF(mvwgetnstr) -#endif - -#ifdef mvwgetstr -inline int UNDEF(mvwgetstr)(WINDOW *win, int y, int x, char *str) -{return mvwgetstr(win, y, x, str);} -#undef mvwgetstr -#define mvwgetstr UNDEF(mvwgetstr) -#endif - -#ifdef mvwhline -inline int UNDEF(mvwhline)(WINDOW *win, int y, int x, chtype c, int n) { - return mvwhline(win, y, x, c, n); } -#undef mvwhline -#define mvwhline UNDEF(mvwhline) -#endif - -#ifdef mvwinch -inline chtype UNDEF(mvwinch)(WINDOW *win, int y, int x) { - return mvwinch(win, y, x);} -#undef mvwinch -#define mvwinch UNDEF(mvwinch) -#endif - -#ifdef mvwinchnstr -inline int UNDEF(mvwinchnstr)(WINDOW *win, int y, int x, chtype *str, int n) { return mvwinchnstr(win, y, x, str, n); } -#undef mvwinchnstr -#define mvwinchnstr UNDEF(mvwinchnstr) -#endif - -#ifdef mvwinchstr -inline int UNDEF(mvwinchstr)(WINDOW *win, int y, int x, chtype *str) { return mvwinchstr(win, y, x, str); } -#undef mvwinchstr -#define mvwinchstr UNDEF(mvwinchstr) -#endif - -#ifdef mvwinnstr -inline int UNDEF(mvwinnstr)(WINDOW *win, int y, int x, char *_str, int n) { - return mvwinnstr(win, y, x, _str, n); } -#undef mvwinnstr -#define mvwinnstr UNDEF(mvwinnstr) -#endif - -#ifdef mvwinsch -inline int UNDEF(mvwinsch)(WINDOW *win, int y, int x, chtype c) -{ return mvwinsch(win, y, x, c); } -#undef mvwinsch -#define mvwinsch UNDEF(mvwinsch) -#endif - -#ifdef mvwinsnstr -inline int UNDEF(mvwinsnstr)(WINDOW *w, int y, int x, const char *_str, int n) { - return mvwinsnstr(w, y, x, _str, n); } -#undef mvwinsnstr -#define mvwinsnstr UNDEF(mvwinsnstr) -#endif - -#ifdef mvwinsstr -inline int UNDEF(mvwinsstr)(WINDOW *w, int y, int x, const char *_str) { - return mvwinsstr(w, y, x, _str); } -#undef mvwinsstr -#define mvwinsstr UNDEF(mvwinsstr) -#endif - -#ifdef mvwvline -inline int UNDEF(mvwvline)(WINDOW *win, int y, int x, chtype c, int n) { - return mvwvline(win, y, x, c, n); } -#undef mvwvline -#define mvwvline UNDEF(mvwvline) -#endif - -#ifdef napms -inline void UNDEF(napms)(unsigned long x) { napms(x); } -#undef napms -#define napms UNDEF(napms) -#endif - -#ifdef nocrmode -inline int UNDEF(nocrmode)(void) { return nocrmode(); } -#undef nocrmode -#define nocrmode UNDEF(nocrmode) -#endif - -#ifdef nodelay -inline void UNDEF(nodelay)() { nodelay(); } -#undef nodelay -#define nodelay UNDEF(nodelay) -#endif - -#ifdef redrawwin -inline int UNDEF(redrawwin)(WINDOW *win) { return redrawwin(win); } -#undef redrawwin -#define redrawwin UNDEF(redrawwin) -#endif - -#ifdef refresh -inline int UNDEF(refresh)() { return refresh(); } -#undef refresh -#define refresh UNDEF(refresh) -#endif - -#ifdef resetterm -inline int UNDEF(resetterm)(void) { return resetterm(); } -#undef resetterm -#define resetterm UNDEF(resetterm) -#endif - -#ifdef saveterm -inline int UNDEF(saveterm)(void) { return saveterm(); } -#undef saveterm -#define saveterm UNDEF(saveterm) -#endif - -#ifdef scrl -inline int UNDEF(scrl)(int l) { return scrl(l); } -#undef scrl -#define scrl UNDEF(scrl) -#endif - -#ifdef scroll -inline int UNDEF(scroll)(WINDOW *win) { return scroll(win); } -#undef scroll -#define scroll UNDEF(scroll) -#endif - -#ifdef scrollok -inline int UNDEF(scrollok)(WINDOW* win, bool bf) { return scrollok(win, bf); } -#undef scrollok -#define scrollok UNDEF(scrollok) -#else -#if defined(__NCURSES_H) -extern "C" NCURSES_IMPEXP int NCURSES_API scrollok(WINDOW*, bool); -#else -extern "C" NCURSES_IMPEXP int NCURSES_API scrollok(WINDOW*, char); -#endif -#endif - -#ifdef setscrreg -inline int UNDEF(setscrreg)(int t, int b) { return setscrreg(t, b); } -#undef setscrreg -#define setscrreg UNDEF(setscrreg) -#endif - -#ifdef standend -inline int UNDEF(standend)() { return standend(); } -#undef standend -#define standend UNDEF(standend) -#endif - -#ifdef standout -inline int UNDEF(standout)() { return standout(); } -#undef standout -#define standout UNDEF(standout) -#endif - -#ifdef subpad -inline WINDOW *UNDEF(subpad)(WINDOW *p, int l, int c, int y, int x) -{ return derwin(p, l, c, y, x); } -#undef subpad -#define subpad UNDEF(subpad) -#endif - -#ifdef timeout -inline void UNDEF(timeout)(int delay) { timeout(delay); } -#undef timeout -#define timeout UNDEF(timeout) -#endif - -#ifdef touchline -inline int UNDEF(touchline)(WINDOW *win, int s, int c) -{ return touchline(win, s, c); } -#undef touchline -#define touchline UNDEF(touchline) -#endif - -#ifdef touchwin -inline int UNDEF(touchwin)(WINDOW *win) { return touchwin(win); } -#undef touchwin -#define touchwin UNDEF(touchwin) -#endif - -#ifdef untouchwin -inline int UNDEF(untouchwin)(WINDOW *win) { return untouchwin(win); } -#undef untouchwin -#define untouchwin UNDEF(untouchwin) -#endif - -#ifdef vline -inline int UNDEF(vline)(chtype ch, int n) { return vline(ch, n); } -#undef vline -#define vline UNDEF(vline) -#endif - -#ifdef waddchstr -inline int UNDEF(waddchstr)(WINDOW *win, chtype *at) { return waddchstr(win, at); } -#undef waddchstr -#define waddchstr UNDEF(waddchstr) -#endif - -#ifdef waddstr -inline int UNDEF(waddstr)(WINDOW *win, char *str) { return waddstr(win, str); } -#undef waddstr -#define waddstr UNDEF(waddstr) -#endif - -#ifdef wattroff -inline int UNDEF(wattroff)(WINDOW *win, int att) { return wattroff(win, att); } -#undef wattroff -#define wattroff UNDEF(wattroff) -#endif - -#ifdef wattrset -inline int UNDEF(wattrset)(WINDOW *win, int att) { return wattrset(win, att); } -#undef wattrset -#define wattrset UNDEF(wattrset) -#endif - -#ifdef winch -inline chtype UNDEF(winch)(const WINDOW* win) { return winch(win); } -#undef winch -#define winch UNDEF(winch) -#endif - -#ifdef winchnstr -inline int UNDEF(winchnstr)(WINDOW *win, chtype *str, int n) { return winchnstr(win, str, n); } -#undef winchnstr -#define winchnstr UNDEF(winchnstr) -#endif - -#ifdef winchstr -inline int UNDEF(winchstr)(WINDOW *win, chtype *str) { return winchstr(win, str); } -#undef winchstr -#define winchstr UNDEF(winchstr) -#endif - -#ifdef winsstr -inline int UNDEF(winsstr)(WINDOW *w, const char *_str) { - return winsstr(w, _str); } -#undef winsstr -#define winsstr UNDEF(winsstr) -#endif - -#ifdef wstandend -inline int UNDEF(wstandend)(WINDOW *win) { return wstandend(win); } -#undef wstandend -#define wstandend UNDEF(wstandend) -#endif - -#ifdef wstandout -inline int UNDEF(wstandout)(WINDOW *win) { return wstandout(win); } -#undef wstandout -#define wstandout UNDEF(wstandout) -#endif - -/* - * - * C++ class for windows. - * - */ - -extern "C" int _nc_ripoffline(int, int (*init)(WINDOW*, int)); -extern "C" int _nc_xx_ripoff_init(WINDOW *, int); -extern "C" int _nc_has_mouse(void); - -class NCURSES_IMPEXP NCursesWindow -{ - friend class NCursesMenu; - friend class NCursesForm; - -private: - static bool b_initialized; - static void initialize(); - void constructing(); - friend int _nc_xx_ripoff_init(WINDOW *, int); - - void set_keyboard(); - - short getcolor(int getback) const; - short getPair() const; - - static int setpalette(short fore, short back, short pair); - static int colorInitialized; - - // This private constructor is only used during the initialization - // of windows generated by ripoffline() calls. - NCursesWindow(WINDOW* win, int ncols); - -protected: - virtual void err_handler(const char *) const THROWS(NCursesException); - // Signal an error with the given message text. - - static long count; // count of all active windows: - // We rely on the c++ promise that - // all otherwise uninitialized - // static class vars are set to 0 - - WINDOW* w; // the curses WINDOW - - bool alloced; // TRUE if we own the WINDOW - - NCursesWindow* par; // parent, if subwindow - NCursesWindow* subwins; // head of subwindows list - NCursesWindow* sib; // next subwindow of parent - - void kill_subwindows(); // disable all subwindows - // Destroy all subwindows. - - /* Only for use by derived classes. They are then in charge to - fill the member variables correctly. */ - NCursesWindow(); - -public: - NCursesWindow(WINDOW* window); // useful only for stdscr - - NCursesWindow(int nlines, // number of lines - int ncols, // number of columns - int begin_y, // line origin - int begin_x); // col origin - - NCursesWindow(NCursesWindow& par,// parent window - int nlines, // number of lines - int ncols, // number of columns - int begin_y, // absolute or relative - int begin_x, // origins: - char absrel = 'a');// if `a', begin_y & begin_x are - // absolute screen pos, else if `r', they are relative to par origin - - NCursesWindow(NCursesWindow& par,// parent window - bool do_box = TRUE); - // this is the very common case that we want to create the subwindow that - // is two lines and two columns smaller and begins at (1,1). - // We may automatically request the box around it. - - NCursesWindow& operator=(const NCursesWindow& rhs) - { - if (this != &rhs) - *this = rhs; - return *this; - } - - NCursesWindow(const NCursesWindow& rhs) - : w(rhs.w), alloced(rhs.alloced), par(rhs.par), subwins(rhs.subwins), sib(rhs.sib) - { - } - - virtual ~NCursesWindow(); - - NCursesWindow Clone(); - // Make an exact copy of the window. - - // Initialization. - static void useColors(void); - // Call this routine very early if you want to have colors. - - static int ripoffline(int ripoff_lines, - int (*init)(NCursesWindow& win)); - // This function is used to generate a window of ripped-of lines. - // If the argument is positive, lines are removed from the top, if it - // is negative lines are removed from the bottom. This enhances the - // lowlevel ripoffline() function because it uses the internal - // implementation that allows to remove more than just a single line. - // This function must be called before any other ncurses function. The - // creation of the window is deferred until ncurses gets initialized. - // The initialization function is then called. - - // ------------------------------------------------------------------------- - // terminal status - // ------------------------------------------------------------------------- - int lines() const { initialize(); return LINES; } - // Number of lines on terminal, *not* window - - int cols() const { initialize(); return COLS; } - // Number of cols on terminal, *not* window - - int tabsize() const { initialize(); return TABSIZE; } - // Size of a tab on terminal, *not* window - - static int NumberOfColors(); - // Number of available colors - - int colors() const { return NumberOfColors(); } - // Number of available colors - - // ------------------------------------------------------------------------- - // window status - // ------------------------------------------------------------------------- - int height() const { return maxy() + 1; } - // Number of lines in this window - - int width() const { return maxx() + 1; } - // Number of columns in this window - - int begx() const { return getbegx(w); } - // Column of top left corner relative to stdscr - - int begy() const { return getbegy(w); } - // Line of top left corner relative to stdscr - - int curx() const { return getcurx(w); } - // Column of top left corner relative to stdscr - - int cury() const { return getcury(w); } - // Line of top left corner relative to stdscr - - int maxx() const { return getmaxx(w) == ERR ? ERR : getmaxx(w)-1; } - // Largest x coord in window - - int maxy() const { return getmaxy(w) == ERR ? ERR : getmaxy(w)-1; } - // Largest y coord in window - - short getcolor() const; - // Actual color pair - - short foreground() const { return getcolor(0); } - // Actual foreground color - - short background() const { return getcolor(1); } - // Actual background color - - int setpalette(short fore, short back); - // Set color palette entry - - int setcolor(short pair); - // Set actually used palette entry - - // ------------------------------------------------------------------------- - // window positioning - // ------------------------------------------------------------------------- - virtual int mvwin(int begin_y, int begin_x) { - return ::mvwin(w, begin_y, begin_x); } - // Move window to new position with the new position as top left corner. - // This is virtual because it is redefined in NCursesPanel. - - // ------------------------------------------------------------------------- - // coordinate positioning - // ------------------------------------------------------------------------- - int move(int y, int x) { return ::wmove(w, y, x); } - // Move cursor the this position - - void getyx(int& y, int& x) const { ::getyx(w, y, x); } - // Get current position of the cursor - - void getbegyx(int& y, int& x) const { ::getbegyx(w, y, x); } - // Get beginning of the window - - void getmaxyx(int& y, int& x) const { ::getmaxyx(w, y, x); } - // Get size of the window - - void getparyx(int& y, int& x) const { ::getparyx(w, y, x); } - // Get parent's beginning of the window - - int mvcur(int oldrow, int oldcol, int newrow, int newcol) const { - return ::mvcur(oldrow, oldcol, newrow, newcol); } - // Perform lowlevel cursor motion that takes effect immediately. - - // ------------------------------------------------------------------------- - // input - // ------------------------------------------------------------------------- - int getch() { return ::wgetch(w); } - // Get a keystroke from the window. - - int getch(int y, int x) { return ::mvwgetch(w, y, x); } - // Move cursor to position and get a keystroke from the window - - int getstr(char* str, int n=-1) { - return ::wgetnstr(w, str, n); } - // Read a series of characters into str until a newline or carriage return - // is received. Read at most n characters. If n is negative, the limit is - // ignored. - - int getstr(int y, int x, char* str, int n=-1) { - return ::mvwgetnstr(w, y, x, str, n); } - // Move the cursor to the requested position and then perform the getstr() - // as described above. - - int instr(char *s, int n=-1) { return ::winnstr(w, s, n); } - // Get a string of characters from the window into the buffer s. Retrieve - // at most n characters, if n is negative retrieve all characters up to the - // end of the current line. Attributes are stripped from the characters. - - int instr(int y, int x, char *s, int n=-1) { - return ::mvwinnstr(w, y, x, s, n); } - // Move the cursor to the requested position and then perform the instr() - // as described above. - - int scanw(const char* fmt, ...) - // Perform a scanw function from the window. -#if __GNUG__ >= 2 - __attribute__ ((format (scanf, 2, 3))); -#else - ; -#endif - - int scanw(const char*, va_list); - // Perform a scanw function from the window. - - int scanw(int y, int x, const char* fmt, ...) - // Move the cursor to the requested position and then perform a scanw - // from the window. -#if __GNUG__ >= 2 - __attribute__ ((format (scanf, 4, 5))); -#else - ; -#endif - - int scanw(int y, int x, const char* fmt, va_list); - // Move the cursor to the requested position and then perform a scanw - // from the window. - - // ------------------------------------------------------------------------- - // output - // ------------------------------------------------------------------------- - int addch(const chtype ch) { return ::waddch(w, ch); } - // Put attributed character to the window. - - int addch(int y, int x, const chtype ch) { - return ::mvwaddch(w, y, x, ch); } - // Move cursor to the requested position and then put attributed character - // to the window. - - int echochar(const chtype ch) { return ::wechochar(w, ch); } - // Put attributed character to the window and refresh it immediately. - - int addstr(const char* str, int n=-1) { - return ::waddnstr(w, str, n); } - // Write the string str to the window, stop writing if the terminating - // NUL or the limit n is reached. If n is negative, it is ignored. - - int addstr(int y, int x, const char * str, int n=-1) { - return ::mvwaddnstr(w, y, x, str, n); } - // Move the cursor to the requested position and then perform the addchstr - // as described above. - - int addchstr(const chtype* str, int n=-1) { - return ::waddchnstr(w, str, n); } - // Write the string str to the window, stop writing if the terminating - // NUL or the limit n is reached. If n is negative, it is ignored. - - int addchstr(int y, int x, const chtype * str, int n=-1) { - return ::mvwaddchnstr(w, y, x, str, n); } - // Move the cursor to the requested position and then perform the addchstr - // as described above. - - int printw(const char* fmt, ...) - // Do a formatted print to the window. -#if (__GNUG__ >= 2) && !defined(printf) - __attribute__ ((format (printf, 2, 3))); -#else - ; -#endif - - int printw(int y, int x, const char * fmt, ...) - // Move the cursor and then do a formatted print to the window. -#if (__GNUG__ >= 2) && !defined(printf) - __attribute__ ((format (printf, 4, 5))); -#else - ; -#endif - - int printw(const char* fmt, va_list args); - // Do a formatted print to the window. - - int printw(int y, int x, const char * fmt, va_list args); - // Move the cursor and then do a formatted print to the window. - - chtype inch() const { return ::winch(w); } - // Retrieve attributed character under the current cursor position. - - chtype inch(int y, int x) { return ::mvwinch(w, y, x); } - // Move cursor to requested position and then retrieve attributed character - // at this position. - - int inchstr(chtype* str, int n=-1) { - return ::winchnstr(w, str, n); } - // Read the string str from the window, stop reading if the terminating - // NUL or the limit n is reached. If n is negative, it is ignored. - - int inchstr(int y, int x, chtype * str, int n=-1) { - return ::mvwinchnstr(w, y, x, str, n); } - // Move the cursor to the requested position and then perform the inchstr - // as described above. - - int insch(chtype ch) { return ::winsch(w, ch); } - // Insert attributed character into the window before current cursor - // position. - - int insch(int y, int x, chtype ch) { - return ::mvwinsch(w, y, x, ch); } - // Move cursor to requested position and then insert the attributed - // character before that position. - - int insertln() { return ::winsdelln(w, 1); } - // Insert an empty line above the current line. - - int insdelln(int n=1) { return ::winsdelln(w, n); } - // If n>0 insert that many lines above the current line. If n<0 delete - // that many lines beginning with the current line. - - int insstr(const char *s, int n=-1) { - return ::winsnstr(w, s, n); } - // Insert the string into the window before the current cursor position. - // Insert stops at end of string or when the limit n is reached. If n is - // negative, it is ignored. - - int insstr(int y, int x, const char *s, int n=-1) { - return ::mvwinsnstr(w, y, x, s, n); } - // Move the cursor to the requested position and then perform the insstr() - // as described above. - - int attron (chtype at) { return ::wattron (w, at); } - // Switch on the window attributes; - - int attroff(chtype at) { return ::wattroff(w, static_cast(at)); } - // Switch off the window attributes; - - int attrset(chtype at) { return ::wattrset(w, static_cast(at)); } - // Set the window attributes; - - chtype attrget() { return ::getattrs(w); } - // Get the window attributes; - - int color_set(short color_pair_number, void* opts=NULL) { - return ::wcolor_set(w, color_pair_number, opts); } - // Set the window color attribute; - - int chgat(int n, attr_t attr, short color, const void *opts=NULL) { - return ::wchgat(w, n, attr, color, opts); } - // Change the attributes of the next n characters in the current line. If - // n is negative or greater than the number of remaining characters in the - // line, the attributes will be changed up to the end of the line. - - int chgat(int y, int x, - int n, attr_t attr, short color, const void *opts=NULL) { - return ::mvwchgat(w, y, x, n, attr, color, opts); } - // Move the cursor to the requested position and then perform chgat() as - // described above. - - // ------------------------------------------------------------------------- - // background - // ------------------------------------------------------------------------- - chtype getbkgd() const { return ::getbkgd(w); } - // Get current background setting. - - int bkgd(const chtype ch) { return ::wbkgd(w, ch); } - // Set the background property and apply it to the window. - - void bkgdset(chtype ch) { ::wbkgdset(w, ch); } - // Set the background property. - - // ------------------------------------------------------------------------- - // borders - // ------------------------------------------------------------------------- - int box(chtype vert=0, chtype hor=0) { - return ::wborder(w, vert, vert, hor, hor, 0, 0, 0, 0); } - // Draw a box around the window with the given vertical and horizontal - // drawing characters. If you specify a zero as character, curses will try - // to find a "nice" character. - - int border(chtype left=0, chtype right=0, - chtype top =0, chtype bottom=0, - chtype top_left =0, chtype top_right=0, - chtype bottom_left =0, chtype bottom_right=0) { - return ::wborder(w, left, right, top, bottom, top_left, top_right, - bottom_left, bottom_right); } - // Draw a border around the window with the given characters for the - // various parts of the border. If you pass zero for a character, curses - // will try to find "nice" characters. - - // ------------------------------------------------------------------------- - // lines and boxes - // ------------------------------------------------------------------------- - int hline(int len, chtype ch=0) { return ::whline(w, ch, len); } - // Draw a horizontal line of len characters with the given character. If - // you pass zero for the character, curses will try to find a "nice" one. - - int hline(int y, int x, int len, chtype ch=0) { - return ::mvwhline(w, y, x, ch, len); } - // Move the cursor to the requested position and then draw a horizontal line. - - int vline(int len, chtype ch=0) { return ::wvline(w, ch, len); } - // Draw a vertical line of len characters with the given character. If - // you pass zero for the character, curses will try to find a "nice" one. - - int vline(int y, int x, int len, chtype ch=0) { - return ::mvwvline(w, y, x, ch, len); } - // Move the cursor to the requested position and then draw a vertical line. - - // ------------------------------------------------------------------------- - // erasure - // ------------------------------------------------------------------------- - int erase() { return ::werase(w); } - // Erase the window. - - int clear() { return ::wclear(w); } - // Clear the window. - - int clearok(bool bf) { return ::clearok(w, bf); } - // Set/Reset the clear flag. If set, the next refresh() will clear the - // screen. - - int clrtobot() { return ::wclrtobot(w); } - // Clear to the end of the window. - - int clrtoeol() { return ::wclrtoeol(w); } - // Clear to the end of the line. - - int delch() { return ::wdelch(w); } - // Delete character under the cursor. - - int delch(int y, int x) { return ::mvwdelch(w, y, x); } - // Move cursor to requested position and delete the character under the - // cursor. - - int deleteln() { return ::winsdelln(w, -1); } - // Delete the current line. - - // ------------------------------------------------------------------------- - // screen control - // ------------------------------------------------------------------------- - int scroll(int amount=1) { return ::wscrl(w, amount); } - // Scroll amount lines. If amount is positive, scroll up, otherwise - // scroll down. - - int scrollok(bool bf) { return ::scrollok(w, bf); } - // If bf is TRUE, window scrolls if cursor is moved off the bottom - // edge of the window or a scrolling region, otherwise the cursor is left - // at the bottom line. - - int setscrreg(int from, int to) { - return ::wsetscrreg(w, from, to); } - // Define a soft scrolling region. - - int idlok(bool bf) { return ::idlok(w, bf); } - // If bf is TRUE, use insert/delete line hardware support if possible. - // Otherwise do it in software. - - void idcok(bool bf) { ::idcok(w, bf); } - // If bf is TRUE, use insert/delete character hardware support if possible. - // Otherwise do it in software. - - int touchline(int s, int c) { return ::touchline(w, s, c); } - // Mark the given lines as modified. - - int touchwin() { return ::wtouchln(w, 0, height(), 1); } - // Mark the whole window as modified. - - int untouchwin() { return ::wtouchln(w, 0, height(), 0); } - // Mark the whole window as unmodified. - - int touchln(int s, int cnt, bool changed=TRUE) { - return ::wtouchln(w, s, cnt, static_cast(changed ? 1 : 0)); } - // Mark cnt lines beginning from line s as changed or unchanged, depending - // on the value of the changed flag. - - bool is_linetouched(int line) const { - return (::is_linetouched(w, line) ? TRUE:FALSE); } - // Return TRUE if line is marked as changed, FALSE otherwise - - bool is_wintouched() const { - return (::is_wintouched(w) ? TRUE:FALSE); } - // Return TRUE if window is marked as changed, FALSE otherwise - - int leaveok(bool bf) { return ::leaveok(w, bf); } - // If bf is TRUE, curses will leave the cursor after an update whereever - // it is after the update. - - int redrawln(int from, int n) { return ::wredrawln(w, from, n); } - // Redraw n lines starting from the requested line - - int redrawwin() { return ::wredrawln(w, 0, height()); } - // Redraw the whole window - - int doupdate() { return ::doupdate(); } - // Do all outputs to make the physical screen looking like the virtual one - - void syncdown() { ::wsyncdown(w); } - // Propagate the changes down to all descendant windows - - void syncup() { ::wsyncup(w); } - // Propagate the changes up in the hierarchy - - void cursyncup() { ::wcursyncup(w); } - // Position the cursor in all ancestor windows corresponding to our setting - - int syncok(bool bf) { return ::syncok(w, bf); } - // If called with bf=TRUE, syncup() is called whenever the window is changed - -#ifndef _no_flushok - int flushok(bool bf) { return ::flushok(w, bf); } -#endif - - void immedok(bool bf) { ::immedok(w, bf); } - // If called with bf=TRUE, any change in the window will cause an - // automatic immediate refresh() - - int intrflush(bool bf) { return ::intrflush(w, bf); } - - int keypad(bool bf) { return ::keypad(w, bf); } - // If called with bf=TRUE, the application will interpret function keys. - - int nodelay(bool bf) { return ::nodelay(w, bf); } - - int meta(bool bf) { return ::meta(w, bf); } - // If called with bf=TRUE, keys may generate 8-Bit characters. Otherwise - // 7-Bit characters are generated. - - int standout() { return ::wstandout(w); } - // Enable "standout" attributes - - int standend() { return ::wstandend(w); } - // Disable "standout" attributes - - // ------------------------------------------------------------------------- - // The next two are virtual, because we redefine them in the - // NCursesPanel class. - // ------------------------------------------------------------------------- - virtual int refresh() { return ::wrefresh(w); } - // Propagate the changes in this window to the virtual screen and call - // doupdate(). This is redefined in NCursesPanel. - - virtual int noutrefresh() { return ::wnoutrefresh(w); } - // Propagate the changes in this window to the virtual screen. This is - // redefined in NCursesPanel. - - // ------------------------------------------------------------------------- - // multiple window control - // ------------------------------------------------------------------------- - int overlay(NCursesWindow& win) { - return ::overlay(w, win.w); } - // Overlay this window over win. - - int overwrite(NCursesWindow& win) { - return ::overwrite(w, win.w); } - // Overwrite win with this window. - - int copywin(NCursesWindow& win, - int sminrow, int smincol, - int dminrow, int dmincol, - int dmaxrow, int dmaxcol, bool overlaywin=TRUE) { - return ::copywin(w, win.w, sminrow, smincol, dminrow, dmincol, - dmaxrow, dmaxcol, static_cast(overlaywin ? 1 : 0)); } - // Overlay or overwrite the rectangle in win given by dminrow,dmincol, - // dmaxrow,dmaxcol with the rectangle in this window beginning at - // sminrow,smincol. - - // ------------------------------------------------------------------------- - // Extended functions - // ------------------------------------------------------------------------- -#if defined(NCURSES_EXT_FUNCS) && (NCURSES_EXT_FUNCS != 0) - int wresize(int newLines, int newColumns) { - return ::wresize(w, newLines, newColumns); } -#endif - - // ------------------------------------------------------------------------- - // Mouse related - // ------------------------------------------------------------------------- - bool has_mouse() const; - // Return TRUE if terminal supports a mouse, FALSE otherwise - - // ------------------------------------------------------------------------- - // traversal support - // ------------------------------------------------------------------------- - NCursesWindow* child() { return subwins; } - // Get the first child window. - - NCursesWindow* sibling() { return sib; } - // Get the next child of my parent. - - NCursesWindow* parent() { return par; } - // Get my parent. - - bool isDescendant(NCursesWindow& win); - // Return TRUE if win is a descendant of this. -}; - -// ------------------------------------------------------------------------- -// We leave this here for compatibility reasons. -// ------------------------------------------------------------------------- -class NCURSES_IMPEXP NCursesColorWindow : public NCursesWindow -{ -public: - NCursesColorWindow(WINDOW* &window) // useful only for stdscr - : NCursesWindow(window) { - useColors(); } - - NCursesColorWindow(int nlines, // number of lines - int ncols, // number of columns - int begin_y, // line origin - int begin_x) // col origin - : NCursesWindow(nlines, ncols, begin_y, begin_x) { - useColors(); } - - NCursesColorWindow(NCursesWindow& parentWin,// parent window - int nlines, // number of lines - int ncols, // number of columns - int begin_y, // absolute or relative - int begin_x, // origins: - char absrel = 'a') // if `a', by & bx are - : NCursesWindow(parentWin, - nlines, ncols, // absolute screen pos, - begin_y, begin_x, // else if `r', they are - absrel ) { // relative to par origin - useColors(); } -}; - -// These enum definitions really belong inside the NCursesPad class, but only -// recent compilers support that feature. - - typedef enum { - REQ_PAD_REFRESH = KEY_MAX + 1, - REQ_PAD_UP, - REQ_PAD_DOWN, - REQ_PAD_LEFT, - REQ_PAD_RIGHT, - REQ_PAD_EXIT - } Pad_Request; - - const Pad_Request PAD_LOW = REQ_PAD_REFRESH; // lowest op-code - const Pad_Request PAD_HIGH = REQ_PAD_EXIT; // highest op-code - -// ------------------------------------------------------------------------- -// Pad Support. We allow an association of a pad with a "real" window -// through which the pad may be viewed. -// ------------------------------------------------------------------------- -class NCURSES_IMPEXP NCursesPad : public NCursesWindow -{ -private: - NCursesWindow* viewWin; // the "viewport" window - NCursesWindow* viewSub; // the "viewport" subwindow - - int h_gridsize, v_gridsize; - -protected: - int min_row, min_col; // top left row/col of the pads display area - - NCursesWindow* Win(void) const { - // Get the window into which the pad should be copied (if any) - return (viewSub?viewSub:(viewWin?viewWin:0)); - } - - NCursesWindow* getWindow(void) const { - return viewWin; - } - - NCursesWindow* getSubWindow(void) const { - return viewSub; - } - - virtual int driver (int key); // Virtualize keystroke key - // The driver translates the keystroke c into an Pad_Request - - virtual void OnUnknownOperation(int pad_req) { - ::beep(); - } - // This is called if the driver returns an unknown op-code - - virtual void OnNavigationError(int pad_req) { - ::beep(); - } - // This is called if a navigation request couldn't be satisfied - - virtual void OnOperation(int pad_req) { - }; - // OnOperation is called if a Pad_Operation was executed and just before - // the refresh() operation is done. - -public: - NCursesPad(int nlines, int ncols); - // create a pad with the given size - - NCursesPad& operator=(const NCursesPad& rhs) - { - if (this != &rhs) { - *this = rhs; - NCursesWindow::operator=(rhs); - } - return *this; - } - - NCursesPad(const NCursesPad& rhs) - : NCursesWindow(rhs), - viewWin(rhs.viewWin), - viewSub(rhs.viewSub), - h_gridsize(rhs.h_gridsize), - v_gridsize(rhs.v_gridsize), - min_row(rhs.min_row), - min_col(rhs.min_col) - { - } - - virtual ~NCursesPad() {} - - int echochar(const chtype ch) { return ::pechochar(w, ch); } - // Put the attributed character onto the pad and immediately do a - // prefresh(). - - int refresh(); - // If a viewport is defined the pad is displayed in this window, otherwise - // this is a noop. - - int refresh(int pminrow, int pmincol, - int sminrow, int smincol, - int smaxrow, int smaxcol) { - return ::prefresh(w, pminrow, pmincol, - sminrow, smincol, smaxrow, smaxcol); - } - // The coordinates sminrow,smincol,smaxrow,smaxcol describe a rectangle - // on the screen. refresh copies a rectangle of this size beginning - // with top left corner pminrow,pmincol onto the screen and calls doupdate(). - - int noutrefresh(); - // If a viewport is defined the pad is displayed in this window, otherwise - // this is a noop. - - int noutrefresh(int pminrow, int pmincol, - int sminrow, int smincol, - int smaxrow, int smaxcol) { - return ::pnoutrefresh(w, pminrow, pmincol, - sminrow, smincol, smaxrow, smaxcol); - } - // Does the same as refresh() but without calling doupdate(). - - virtual void setWindow(NCursesWindow& view, int v_grid = 1, int h_grid = 1); - // Add the window "view" as viewing window to the pad. - - virtual void setSubWindow(NCursesWindow& sub); - // Use the subwindow "sub" of the viewport window for the actual viewing. - // The full viewport window is usually used to provide some decorations - // like frames, titles etc. - - virtual void operator() (void); - // Perform Pad's operation -}; - -// A FramedPad is constructed always with a viewport window. This viewport -// will be framed (by a box() command) and the interior of the box is the -// viewport subwindow. On the frame we display scrollbar sliders. -class NCURSES_IMPEXP NCursesFramedPad : public NCursesPad -{ -protected: - virtual void OnOperation(int pad_req); - -public: - NCursesFramedPad(NCursesWindow& win, int nlines, int ncols, - int v_grid = 1, int h_grid = 1) - : NCursesPad(nlines, ncols) { - NCursesPad::setWindow(win, v_grid, h_grid); - NCursesPad::setSubWindow(*(new NCursesWindow(win))); - } - // Construct the FramedPad with the given Window win as viewport. - - virtual ~NCursesFramedPad() { - delete getSubWindow(); - } - - void setWindow(NCursesWindow& view, int v_grid = 1, int h_grid = 1) { - err_handler("Operation not allowed"); - } - // Disable this call; the viewport is already defined - - void setSubWindow(NCursesWindow& sub) { - err_handler("Operation not allowed"); - } - // Disable this call; the viewport subwindow is already defined - -}; - -#endif /* NCURSES_CURSESW_H_incl */ diff --git a/windows/ncurses/include/ncurses/cursslk.h b/windows/ncurses/include/ncurses/cursslk.h deleted file mode 100644 index 4c64f402e..000000000 --- a/windows/ncurses/include/ncurses/cursslk.h +++ /dev/null @@ -1,238 +0,0 @@ -// * this is for making emacs happy: -*-Mode: C++;-*- -/**************************************************************************** - * Copyright (c) 1998-2003,2005 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Juergen Pfeifer, 1997 * - ****************************************************************************/ - -// $Id: cursslk.h,v 1.13 2005/05/28 21:58:18 tom Exp $ - -#ifndef NCURSES_CURSSLK_H_incl -#define NCURSES_CURSSLK_H_incl - -#include - -class NCURSES_IMPEXP Soft_Label_Key_Set { -public: - // This inner class represents the attributes of a Soft Label Key (SLK) - class NCURSES_IMPEXP Soft_Label_Key { - friend class Soft_Label_Key_Set; - public: - typedef enum { Left=0, Center=1, Right=2 } Justification; - - private: - char *label; // The Text of the Label - Justification format; // The Justification - int num; // The number of the Label - - Soft_Label_Key() : label(NULL), format(Left), num(-1) { - } - - virtual ~Soft_Label_Key() { - delete[] label; - }; - - public: - // Set the text of the Label - Soft_Label_Key& operator=(char *text); - - // Set the Justification of the Label - Soft_Label_Key& operator=(Justification just) { - format = just; - return *this; - } - - // Retrieve the text of the label - inline char* operator()(void) const { - return label; - } - - Soft_Label_Key& operator=(const Soft_Label_Key& rhs) - { - if (this != &rhs) { - *this = rhs; - } - return *this; - } - - Soft_Label_Key(const Soft_Label_Key& rhs) - : label(NULL), - format(rhs.format), - num(rhs.num) - { - *this = rhs.label; - } - }; - -public: - typedef enum { - None = -1, - Three_Two_Three = 0, - Four_Four = 1, - PC_Style = 2, - PC_Style_With_Index = 3 - } Label_Layout; - -private: - static long NCURSES_IMPEXP count; // Number of Key Sets - static Label_Layout NCURSES_IMPEXP format; // Layout of the Key Sets - static int NCURSES_IMPEXP num_labels; // Number Of Labels in Key Sets - bool NCURSES_IMPEXP b_attrInit; // Are attributes initialized - - Soft_Label_Key *slk_array; // The array of SLK's - - // Init the Key Set - void init(); - - // Activate or Deactivate Label# i, Label counting starts with 1! - void activate_label(int i, bool bf=TRUE); - - // Activate of Deactivate all Labels - void activate_labels(bool bf); - -protected: - inline void Error (const char* msg) const THROWS(NCursesException) { - THROW(new NCursesException (msg)); - } - - // Remove SLK's from screen - void clear() { - if (ERR==::slk_clear()) - Error("slk_clear"); - } - - // Restore them - void restore() { - if (ERR==::slk_restore()) - Error("slk_restore"); - } - -public: - - // Construct a Key Set, use the most comfortable layout as default. - // You must create a Soft_Label_Key_Set before you create any object of - // the NCursesWindow, NCursesPanel or derived classes. (Actually before - // ::initscr() is called). - Soft_Label_Key_Set(Label_Layout fmt); - - // This constructor assumes, that you already constructed a Key Set - // with a layout by the constructor above. This layout will be reused. - NCURSES_IMPEXP Soft_Label_Key_Set(); - - Soft_Label_Key_Set& operator=(const Soft_Label_Key_Set& rhs) - { - if (this != &rhs) { - *this = rhs; - init(); // allocate a new slk_array[] - } - return *this; - } - - Soft_Label_Key_Set(const Soft_Label_Key_Set& rhs) - : b_attrInit(rhs.b_attrInit), - slk_array(NULL) - { - init(); // allocate a new slk_array[] - } - - virtual ~Soft_Label_Key_Set(); - - // Get Label# i. Label counting starts with 1! - NCURSES_IMPEXP Soft_Label_Key& operator[](int i); - - // Retrieve number of Labels - inline int labels() const { return num_labels; } - - // Refresh the SLK portion of the screen - inline void refresh() { - if (ERR==::slk_refresh()) - Error("slk_refresh"); - } - - // Mark the SLK portion of the screen for refresh, defer actual refresh - // until next update call. - inline void noutrefresh() { - if (ERR==::slk_noutrefresh()) - Error("slk_noutrefresh"); - } - - // Mark the whole SLK portion of the screen as modified - inline void touch() { - if (ERR==::slk_touch()) - Error("slk_touch"); - } - - // Activate Label# i - inline void show(int i) { - activate_label(i,FALSE); - activate_label(i,TRUE); - } - - // Hide Label# i - inline void hide(int i) { - activate_label(i,FALSE); - } - - // Show all Labels - inline void show() { - activate_labels(FALSE); - activate_labels(TRUE); - } - - // Hide all Labels - inline void hide() { - activate_labels(FALSE); - } - - inline void attron(attr_t attrs) { - if (ERR==::slk_attron(attrs)) - Error("slk_attron"); - } - - inline void attroff(attr_t attrs) { - if (ERR==::slk_attroff(attrs)) - Error("slk_attroff"); - } - - inline void attrset(attr_t attrs) { - if (ERR==::slk_attrset(attrs)) - Error("slk_attrset"); - } - - inline void color(short color_pair_number) { - if (ERR==::slk_color(color_pair_number)) - Error("slk_color"); - } - - inline attr_t attr() const { - return ::slk_attr(); - } -}; - -#endif /* NCURSES_CURSSLK_H_incl */ diff --git a/windows/ncurses/include/ncurses/eti.h b/windows/ncurses/include/ncurses/eti.h deleted file mode 100644 index baa6190d8..000000000 --- a/windows/ncurses/include/ncurses/eti.h +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2002,2003 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Juergen Pfeifer, 1995,1997 * - ****************************************************************************/ - -/* $Id: eti.h,v 1.8 2003/10/25 15:24:29 tom Exp $ */ - -#ifndef NCURSES_ETI_H_incl -#define NCURSES_ETI_H_incl 1 - -#define E_OK (0) -#define E_SYSTEM_ERROR (-1) -#define E_BAD_ARGUMENT (-2) -#define E_POSTED (-3) -#define E_CONNECTED (-4) -#define E_BAD_STATE (-5) -#define E_NO_ROOM (-6) -#define E_NOT_POSTED (-7) -#define E_UNKNOWN_COMMAND (-8) -#define E_NO_MATCH (-9) -#define E_NOT_SELECTABLE (-10) -#define E_NOT_CONNECTED (-11) -#define E_REQUEST_DENIED (-12) -#define E_INVALID_FIELD (-13) -#define E_CURRENT (-14) - -#endif diff --git a/windows/ncurses/include/ncurses/etip.h b/windows/ncurses/include/ncurses/etip.h deleted file mode 100644 index 82e9409cf..000000000 --- a/windows/ncurses/include/ncurses/etip.h +++ /dev/null @@ -1,378 +0,0 @@ -// * This makes emacs happy -*-Mode: C++;-*- -/**************************************************************************** - * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Juergen Pfeifer, 1997 * - ****************************************************************************/ - -// $Id: etip.h.in,v 1.37 2008/08/30 19:27:32 tom Exp $ - -#ifndef NCURSES_ETIP_H_incl -#define NCURSES_ETIP_H_incl 1 - -// These are substituted at configure/build time -#ifndef HAVE_BUILTIN_H -#define HAVE_BUILTIN_H 0 -#endif - -#ifndef HAVE_GXX_BUILTIN_H -#define HAVE_GXX_BUILTIN_H 0 -#endif - -#ifndef HAVE_GPP_BUILTIN_H -#define HAVE_GPP_BUILTIN_H 0 -#endif - -#ifndef HAVE_IOSTREAM -#define HAVE_IOSTREAM 1 -#endif - -#ifndef HAVE_TYPEINFO -#define HAVE_TYPEINFO 1 -#endif - -#ifndef HAVE_VALUES_H -#define HAVE_VALUES_H 0 -#endif - -#ifndef ETIP_NEEDS_MATH_H -#define ETIP_NEEDS_MATH_H 0 -#endif - -#ifndef ETIP_NEEDS_MATH_EXCEPTION -#define ETIP_NEEDS_MATH_EXCEPTION 0 -#endif - -#ifndef CPP_HAS_PARAM_INIT -#define CPP_HAS_PARAM_INIT 0 -#endif - -#ifndef CPP_HAS_STATIC_CAST -#define CPP_HAS_STATIC_CAST 1 -#endif - -#ifndef IOSTREAM_NAMESPACE -#define IOSTREAM_NAMESPACE 1 -#endif - -#ifdef __GNUG__ -# if ((__GNUG__ <= 2) && (__GNUC_MINOR__ < 8)) -# if HAVE_TYPEINFO -# include -# endif -# endif -#endif - -#if defined(__GNUG__) -# if HAVE_BUILTIN_H || HAVE_GXX_BUILTIN_H || HAVE_GPP_BUILTIN_H -# if ETIP_NEEDS_MATH_H -# if ETIP_NEEDS_MATH_EXCEPTION -# undef exception -# define exception math_exception -# endif -# include -# endif -# undef exception -# define exception builtin_exception -# if HAVE_GPP_BUILTIN_H -# include -# elif HAVE_GXX_BUILTIN_H -# include -# else -# include -# endif -# undef exception -# endif -#elif defined (__SUNPRO_CC) -# include -#endif - -#include - -extern "C" { -#if HAVE_VALUES_H -# include -#endif - -#include -#include -#include -} - -// Language features -#if CPP_HAS_PARAM_INIT -#define NCURSES_PARAM_INIT(value) = value -#else -#define NCURSES_PARAM_INIT(value) /*nothing*/ -#endif - -#if CPP_HAS_STATIC_CAST -#define STATIC_CAST(s) static_cast -#else -#define STATIC_CAST(s) (s) -#endif - -// Forward Declarations -class NCURSES_IMPEXP NCursesPanel; -class NCURSES_IMPEXP NCursesMenu; -class NCURSES_IMPEXP NCursesForm; - -class NCURSES_IMPEXP NCursesException -{ -public: - const char *message; - int errorno; - - NCursesException (const char* msg, int err) - : message(msg), errorno (err) - {}; - - NCursesException (const char* msg) - : message(msg), errorno (E_SYSTEM_ERROR) - {}; - - NCursesException& operator=(const NCursesException& rhs) - { - errorno = rhs.errorno; - return *this; - } - - NCursesException(const NCursesException& rhs) - : message(rhs.message), errorno(rhs.errorno) - { - } - - virtual const char *classname() const { - return "NCursesWindow"; - } - - virtual ~NCursesException() - { - } -}; - -class NCURSES_IMPEXP NCursesPanelException : public NCursesException -{ -public: - const NCursesPanel* p; - - NCursesPanelException (const char *msg, int err) : - NCursesException (msg, err), - p (NULL) - {}; - - NCursesPanelException (const NCursesPanel* panel, - const char *msg, - int err) : - NCursesException (msg, err), - p (panel) - {}; - - NCursesPanelException (int err) : - NCursesException ("panel library error", err), - p (NULL) - {}; - - NCursesPanelException (const NCursesPanel* panel, - int err) : - NCursesException ("panel library error", err), - p (panel) - {}; - - NCursesPanelException& operator=(const NCursesPanelException& rhs) - { - if (this != &rhs) { - NCursesException::operator=(rhs); - p = rhs.p; - } - return *this; - } - - NCursesPanelException(const NCursesPanelException& rhs) - : NCursesException(rhs), p(rhs.p) - { - } - - virtual const char *classname() const { - return "NCursesPanel"; - } - - virtual ~NCursesPanelException() - { - } -}; - -class NCURSES_IMPEXP NCursesMenuException : public NCursesException -{ -public: - const NCursesMenu* m; - - NCursesMenuException (const char *msg, int err) : - NCursesException (msg, err), - m (NULL) - {}; - - NCursesMenuException (const NCursesMenu* menu, - const char *msg, - int err) : - NCursesException (msg, err), - m (menu) - {}; - - NCursesMenuException (int err) : - NCursesException ("menu library error", err), - m (NULL) - {}; - - NCursesMenuException (const NCursesMenu* menu, - int err) : - NCursesException ("menu library error", err), - m (menu) - {}; - - NCursesMenuException& operator=(const NCursesMenuException& rhs) - { - if (this != &rhs) { - NCursesException::operator=(rhs); - m = rhs.m; - } - return *this; - } - - NCursesMenuException(const NCursesMenuException& rhs) - : NCursesException(rhs), m(rhs.m) - { - } - - virtual const char *classname() const { - return "NCursesMenu"; - } - - virtual ~NCursesMenuException() - { - } -}; - -class NCURSES_IMPEXP NCursesFormException : public NCursesException -{ -public: - const NCursesForm* f; - - NCursesFormException (const char *msg, int err) : - NCursesException (msg, err), - f (NULL) - {}; - - NCursesFormException (const NCursesForm* form, - const char *msg, - int err) : - NCursesException (msg, err), - f (form) - {}; - - NCursesFormException (int err) : - NCursesException ("form library error", err), - f (NULL) - {}; - - NCursesFormException (const NCursesForm* form, - int err) : - NCursesException ("form library error", err), - f (form) - {}; - - NCursesFormException& operator=(const NCursesFormException& rhs) - { - if (this != &rhs) { - NCursesException::operator=(rhs); - f = rhs.f; - } - return *this; - } - - NCursesFormException(const NCursesFormException& rhs) - : NCursesException(rhs), f(rhs.f) - { - } - - virtual const char *classname() const { - return "NCursesForm"; - } - - virtual ~NCursesFormException() - { - } -}; - -#if !((defined(__GNUG__) && defined(__EXCEPTIONS)) || defined(__SUNPRO_CC)) -# if HAVE_IOSTREAM -# include -# if IOSTREAM_NAMESPACE -using std::cerr; -using std::endl; -# endif -# else -# include -# endif - extern "C" void exit(int); -#endif - -inline void THROW(const NCursesException *e) { -#if defined(__GNUG__) && defined(__EXCEPTIONS) -# if ((__GNUG__ <= 2) && (__GNUC_MINOR__ < 8)) - (*lib_error_handler)(e ? e->classname() : "", e ? e->message : ""); -#else -#define CPP_HAS_TRY_CATCH 1 -#endif -#elif defined(__SUNPRO_CC) -# if !defined(__SUNPRO_CC_COMPAT) || (__SUNPRO_CC_COMPAT < 5) - genericerror(1, ((e != 0) ? (char *)(e->message) : "")); -#else -#define CPP_HAS_TRY_CATCH 1 -#endif -#else - if (e) - cerr << e->message << endl; - exit(0); -#endif - -#ifndef CPP_HAS_TRY_CATCH -#define CPP_HAS_TRY_CATCH 0 -#define NCURSES_CPP_TRY /* nothing */ -#define NCURSES_CPP_CATCH(e) if (false) -#define THROWS(s) /* nothing */ -#elif CPP_HAS_TRY_CATCH - throw *e; -#define NCURSES_CPP_TRY try -#define NCURSES_CPP_CATCH(e) catch(e) -#define THROWS(s) throw(s) -#endif -} - -#endif /* NCURSES_ETIP_H_incl */ diff --git a/windows/ncurses/include/ncurses/form.h b/windows/ncurses/include/ncurses/form.h deleted file mode 100644 index 80886ac3a..000000000 --- a/windows/ncurses/include/ncurses/form.h +++ /dev/null @@ -1,422 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2004,2009 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Juergen Pfeifer, 1995,1997 * - ****************************************************************************/ - -/* $Id: form.h,v 0.21 2009/11/07 19:31:11 tom Exp $ */ - -#ifndef FORM_H -#define FORM_H - -#include -#include - -#ifdef __cplusplus - extern "C" { -#endif - -#ifndef FORM_PRIV_H -typedef void *FIELD_CELL; -#endif - -#ifndef NCURSES_FIELD_INTERNALS -#define NCURSES_FIELD_INTERNALS /* nothing */ -#endif - -typedef int Form_Options; -typedef int Field_Options; - - /********** - * _PAGE * - **********/ - -typedef struct { - short pmin; /* index of first field on page */ - short pmax; /* index of last field on page */ - short smin; /* index of top leftmost field on page */ - short smax; /* index of bottom rightmost field on page */ -} _PAGE; - - /********** - * FIELD * - **********/ - -typedef struct fieldnode { - unsigned short status; /* flags */ - short rows; /* size in rows */ - short cols; /* size in cols */ - short frow; /* first row */ - short fcol; /* first col */ - int drows; /* dynamic rows */ - int dcols; /* dynamic cols */ - int maxgrow; /* maximum field growth */ - int nrow; /* off-screen rows */ - short nbuf; /* additional buffers */ - short just; /* justification */ - short page; /* page on form */ - short index; /* into form -> field */ - int pad; /* pad character */ - chtype fore; /* foreground attribute */ - chtype back; /* background attribute */ - Field_Options opts; /* options */ - struct fieldnode * snext; /* sorted order pointer */ - struct fieldnode * sprev; /* sorted order pointer */ - struct fieldnode * link; /* linked field chain */ - struct formnode * form; /* containing form */ - struct typenode * type; /* field type */ - void * arg; /* argument for type */ - FIELD_CELL * buf; /* field buffers */ - void * usrptr; /* user pointer */ - /* - * The wide-character configuration requires extra information. Because - * there are existing applications that manipulate the members of FIELD - * directly, we cannot make the struct opaque. Offsets of members up to - * this point are the same in the narrow- and wide-character configuration. - * But note that the type of buf depends on the configuration, and is made - * opaque for that reason. - */ - NCURSES_FIELD_INTERNALS -} FIELD; - - - /********* - * FORM * - *********/ - -typedef struct formnode { - unsigned short status; /* flags */ - short rows; /* size in rows */ - short cols; /* size in cols */ - int currow; /* current row in field window */ - int curcol; /* current col in field window */ - int toprow; /* in scrollable field window */ - int begincol; /* in horiz. scrollable field */ - short maxfield; /* number of fields */ - short maxpage; /* number of pages */ - short curpage; /* index into page */ - Form_Options opts; /* options */ - WINDOW * win; /* window */ - WINDOW * sub; /* subwindow */ - WINDOW * w; /* window for current field */ - FIELD ** field; /* field [maxfield] */ - FIELD * current; /* current field */ - _PAGE * page; /* page [maxpage] */ - void * usrptr; /* user pointer */ - - void (*forminit)(struct formnode *); - void (*formterm)(struct formnode *); - void (*fieldinit)(struct formnode *); - void (*fieldterm)(struct formnode *); - -} FORM; - - - /************** - * FIELDTYPE * - **************/ - -typedef struct typenode { - unsigned short status; /* flags */ - long ref; /* reference count */ - struct typenode * left; /* ptr to operand for | */ - struct typenode * right; /* ptr to operand for | */ - - void* (*makearg)(va_list *); /* make fieldtype arg */ - void* (*copyarg)(const void *); /* copy fieldtype arg */ - void (*freearg)(void *); /* free fieldtype arg */ - -#if NCURSES_INTEROP_FUNCS - union { - bool (*ofcheck)(FIELD *,const void *); /* field validation */ - bool (*gfcheck)(FORM*,FIELD *,const void*); /* generic field validation */ - } fieldcheck; - union { - bool (*occheck)(int,const void *); /* character validation */ - bool (*gccheck)(int,FORM*, - FIELD*,const void*); /* generic char validation */ - } charcheck; - union { - bool (*onext)(FIELD *,const void *); /* enumerate next value */ - bool (*gnext)(FORM*,FIELD*,const void*); /* generic enumerate next */ - } enum_next; - union { - bool (*oprev)(FIELD *,const void *); /* enumerate prev value */ - bool (*gprev)(FORM*,FIELD*,const void*); /* generic enumerate prev */ - } enum_prev; - void* (*genericarg)(void*); /* Alternate Arg method */ -#else - bool (*fcheck)(FIELD *,const void *); /* field validation */ - bool (*ccheck)(int,const void *); /* character validation */ - - bool (*next)(FIELD *,const void *); /* enumerate next value */ - bool (*prev)(FIELD *,const void *); /* enumerate prev value */ -#endif -} FIELDTYPE; - -typedef void (*Form_Hook)(FORM *); - - /*************************** - * miscellaneous #defines * - ***************************/ - -/* field justification */ -#define NO_JUSTIFICATION (0) -#define JUSTIFY_LEFT (1) -#define JUSTIFY_CENTER (2) -#define JUSTIFY_RIGHT (3) - -/* field options */ -#define O_VISIBLE (0x0001U) -#define O_ACTIVE (0x0002U) -#define O_PUBLIC (0x0004U) -#define O_EDIT (0x0008U) -#define O_WRAP (0x0010U) -#define O_BLANK (0x0020U) -#define O_AUTOSKIP (0x0040U) -#define O_NULLOK (0x0080U) -#define O_PASSOK (0x0100U) -#define O_STATIC (0x0200U) - -/* form options */ -#define O_NL_OVERLOAD (0x0001U) -#define O_BS_OVERLOAD (0x0002U) - -/* form driver commands */ -#define REQ_NEXT_PAGE (KEY_MAX + 1) /* move to next page */ -#define REQ_PREV_PAGE (KEY_MAX + 2) /* move to previous page */ -#define REQ_FIRST_PAGE (KEY_MAX + 3) /* move to first page */ -#define REQ_LAST_PAGE (KEY_MAX + 4) /* move to last page */ - -#define REQ_NEXT_FIELD (KEY_MAX + 5) /* move to next field */ -#define REQ_PREV_FIELD (KEY_MAX + 6) /* move to previous field */ -#define REQ_FIRST_FIELD (KEY_MAX + 7) /* move to first field */ -#define REQ_LAST_FIELD (KEY_MAX + 8) /* move to last field */ -#define REQ_SNEXT_FIELD (KEY_MAX + 9) /* move to sorted next field */ -#define REQ_SPREV_FIELD (KEY_MAX + 10) /* move to sorted prev field */ -#define REQ_SFIRST_FIELD (KEY_MAX + 11) /* move to sorted first field */ -#define REQ_SLAST_FIELD (KEY_MAX + 12) /* move to sorted last field */ -#define REQ_LEFT_FIELD (KEY_MAX + 13) /* move to left to field */ -#define REQ_RIGHT_FIELD (KEY_MAX + 14) /* move to right to field */ -#define REQ_UP_FIELD (KEY_MAX + 15) /* move to up to field */ -#define REQ_DOWN_FIELD (KEY_MAX + 16) /* move to down to field */ - -#define REQ_NEXT_CHAR (KEY_MAX + 17) /* move to next char in field */ -#define REQ_PREV_CHAR (KEY_MAX + 18) /* move to prev char in field */ -#define REQ_NEXT_LINE (KEY_MAX + 19) /* move to next line in field */ -#define REQ_PREV_LINE (KEY_MAX + 20) /* move to prev line in field */ -#define REQ_NEXT_WORD (KEY_MAX + 21) /* move to next word in field */ -#define REQ_PREV_WORD (KEY_MAX + 22) /* move to prev word in field */ -#define REQ_BEG_FIELD (KEY_MAX + 23) /* move to first char in field */ -#define REQ_END_FIELD (KEY_MAX + 24) /* move after last char in fld */ -#define REQ_BEG_LINE (KEY_MAX + 25) /* move to beginning of line */ -#define REQ_END_LINE (KEY_MAX + 26) /* move after last char in line */ -#define REQ_LEFT_CHAR (KEY_MAX + 27) /* move left in field */ -#define REQ_RIGHT_CHAR (KEY_MAX + 28) /* move right in field */ -#define REQ_UP_CHAR (KEY_MAX + 29) /* move up in field */ -#define REQ_DOWN_CHAR (KEY_MAX + 30) /* move down in field */ - -#define REQ_NEW_LINE (KEY_MAX + 31) /* insert/overlay new line */ -#define REQ_INS_CHAR (KEY_MAX + 32) /* insert blank char at cursor */ -#define REQ_INS_LINE (KEY_MAX + 33) /* insert blank line at cursor */ -#define REQ_DEL_CHAR (KEY_MAX + 34) /* delete char at cursor */ -#define REQ_DEL_PREV (KEY_MAX + 35) /* delete char before cursor */ -#define REQ_DEL_LINE (KEY_MAX + 36) /* delete line at cursor */ -#define REQ_DEL_WORD (KEY_MAX + 37) /* delete word at cursor */ -#define REQ_CLR_EOL (KEY_MAX + 38) /* clear to end of line */ -#define REQ_CLR_EOF (KEY_MAX + 39) /* clear to end of field */ -#define REQ_CLR_FIELD (KEY_MAX + 40) /* clear entire field */ -#define REQ_OVL_MODE (KEY_MAX + 41) /* begin overlay mode */ -#define REQ_INS_MODE (KEY_MAX + 42) /* begin insert mode */ -#define REQ_SCR_FLINE (KEY_MAX + 43) /* scroll field forward a line */ -#define REQ_SCR_BLINE (KEY_MAX + 44) /* scroll field backward a line */ -#define REQ_SCR_FPAGE (KEY_MAX + 45) /* scroll field forward a page */ -#define REQ_SCR_BPAGE (KEY_MAX + 46) /* scroll field backward a page */ -#define REQ_SCR_FHPAGE (KEY_MAX + 47) /* scroll field forward half page */ -#define REQ_SCR_BHPAGE (KEY_MAX + 48) /* scroll field backward half page */ -#define REQ_SCR_FCHAR (KEY_MAX + 49) /* horizontal scroll char */ -#define REQ_SCR_BCHAR (KEY_MAX + 50) /* horizontal scroll char */ -#define REQ_SCR_HFLINE (KEY_MAX + 51) /* horizontal scroll line */ -#define REQ_SCR_HBLINE (KEY_MAX + 52) /* horizontal scroll line */ -#define REQ_SCR_HFHALF (KEY_MAX + 53) /* horizontal scroll half line */ -#define REQ_SCR_HBHALF (KEY_MAX + 54) /* horizontal scroll half line */ - -#define REQ_VALIDATION (KEY_MAX + 55) /* validate field */ -#define REQ_NEXT_CHOICE (KEY_MAX + 56) /* display next field choice */ -#define REQ_PREV_CHOICE (KEY_MAX + 57) /* display prev field choice */ - -#define MIN_FORM_COMMAND (KEY_MAX + 1) /* used by form_driver */ -#define MAX_FORM_COMMAND (KEY_MAX + 57) /* used by form_driver */ - -#if defined(MAX_COMMAND) -# if (MAX_FORM_COMMAND > MAX_COMMAND) -# error Something is wrong -- MAX_FORM_COMMAND is greater than MAX_COMMAND -# elif (MAX_COMMAND != (KEY_MAX + 128)) -# error Something is wrong -- MAX_COMMAND is already inconsistently defined. -# endif -#else -# define MAX_COMMAND (KEY_MAX + 128) -#endif - - /************************* - * standard field types * - *************************/ -extern NCURSES_EXPORT_VAR(FIELDTYPE *) TYPE_ALPHA; -extern NCURSES_EXPORT_VAR(FIELDTYPE *) TYPE_ALNUM; -extern NCURSES_EXPORT_VAR(FIELDTYPE *) TYPE_ENUM; -extern NCURSES_EXPORT_VAR(FIELDTYPE *) TYPE_INTEGER; -extern NCURSES_EXPORT_VAR(FIELDTYPE *) TYPE_NUMERIC; -extern NCURSES_EXPORT_VAR(FIELDTYPE *) TYPE_REGEXP; - - /************************************ - * built-in additional field types * - * They are not defined in SVr4 * - ************************************/ -extern NCURSES_EXPORT_VAR(FIELDTYPE *) TYPE_IPV4; /* Internet IP Version 4 address */ - - /*********************** - * FIELDTYPE routines * - ***********************/ -extern NCURSES_EXPORT(FIELDTYPE *) new_fieldtype ( - bool (* const field_check)(FIELD *,const void *), - bool (* const char_check)(int,const void *)); -extern NCURSES_EXPORT(FIELDTYPE *) link_fieldtype( - FIELDTYPE *, FIELDTYPE *); - -extern NCURSES_EXPORT(int) free_fieldtype (FIELDTYPE *); -extern NCURSES_EXPORT(int) set_fieldtype_arg (FIELDTYPE *, - void * (* const make_arg)(va_list *), - void * (* const copy_arg)(const void *), - void (* const free_arg)(void *)); -extern NCURSES_EXPORT(int) set_fieldtype_choice (FIELDTYPE *, - bool (* const next_choice)(FIELD *,const void *), - bool (* const prev_choice)(FIELD *,const void *)); - - /******************* - * FIELD routines * - *******************/ -extern NCURSES_EXPORT(FIELD *) new_field (int,int,int,int,int,int); -extern NCURSES_EXPORT(FIELD *) dup_field (FIELD *,int,int); -extern NCURSES_EXPORT(FIELD *) link_field (FIELD *,int,int); - -extern NCURSES_EXPORT(int) free_field (FIELD *); -extern NCURSES_EXPORT(int) field_info (const FIELD *,int *,int *,int *,int *,int *,int *); -extern NCURSES_EXPORT(int) dynamic_field_info (const FIELD *,int *,int *,int *); -extern NCURSES_EXPORT(int) set_max_field ( FIELD *,int); -extern NCURSES_EXPORT(int) move_field (FIELD *,int,int); -extern NCURSES_EXPORT(int) set_field_type (FIELD *,FIELDTYPE *,...); -extern NCURSES_EXPORT(int) set_new_page (FIELD *,bool); -extern NCURSES_EXPORT(int) set_field_just (FIELD *,int); -extern NCURSES_EXPORT(int) field_just (const FIELD *); -extern NCURSES_EXPORT(int) set_field_fore (FIELD *,chtype); -extern NCURSES_EXPORT(int) set_field_back (FIELD *,chtype); -extern NCURSES_EXPORT(int) set_field_pad (FIELD *,int); -extern NCURSES_EXPORT(int) field_pad (const FIELD *); -extern NCURSES_EXPORT(int) set_field_buffer (FIELD *,int,const char *); -extern NCURSES_EXPORT(int) set_field_status (FIELD *,bool); -extern NCURSES_EXPORT(int) set_field_userptr (FIELD *, void *); -extern NCURSES_EXPORT(int) set_field_opts (FIELD *,Field_Options); -extern NCURSES_EXPORT(int) field_opts_on (FIELD *,Field_Options); -extern NCURSES_EXPORT(int) field_opts_off (FIELD *,Field_Options); - -extern NCURSES_EXPORT(chtype) field_fore (const FIELD *); -extern NCURSES_EXPORT(chtype) field_back (const FIELD *); - -extern NCURSES_EXPORT(bool) new_page (const FIELD *); -extern NCURSES_EXPORT(bool) field_status (const FIELD *); - -extern NCURSES_EXPORT(void *) field_arg (const FIELD *); - -extern NCURSES_EXPORT(void *) field_userptr (const FIELD *); - -extern NCURSES_EXPORT(FIELDTYPE *) field_type (const FIELD *); - -extern NCURSES_EXPORT(char *) field_buffer (const FIELD *,int); - -extern NCURSES_EXPORT(Field_Options) field_opts (const FIELD *); - - /****************** - * FORM routines * - ******************/ - -extern NCURSES_EXPORT(FORM *) new_form (FIELD **); - -extern NCURSES_EXPORT(FIELD **) form_fields (const FORM *); -extern NCURSES_EXPORT(FIELD *) current_field (const FORM *); - -extern NCURSES_EXPORT(WINDOW *) form_win (const FORM *); -extern NCURSES_EXPORT(WINDOW *) form_sub (const FORM *); - -extern NCURSES_EXPORT(Form_Hook) form_init (const FORM *); -extern NCURSES_EXPORT(Form_Hook) form_term (const FORM *); -extern NCURSES_EXPORT(Form_Hook) field_init (const FORM *); -extern NCURSES_EXPORT(Form_Hook) field_term (const FORM *); - -extern NCURSES_EXPORT(int) free_form (FORM *); -extern NCURSES_EXPORT(int) set_form_fields (FORM *,FIELD **); -extern NCURSES_EXPORT(int) field_count (const FORM *); -extern NCURSES_EXPORT(int) set_form_win (FORM *,WINDOW *); -extern NCURSES_EXPORT(int) set_form_sub (FORM *,WINDOW *); -extern NCURSES_EXPORT(int) set_current_field (FORM *,FIELD *); -extern NCURSES_EXPORT(int) field_index (const FIELD *); -extern NCURSES_EXPORT(int) set_form_page (FORM *,int); -extern NCURSES_EXPORT(int) form_page (const FORM *); -extern NCURSES_EXPORT(int) scale_form (const FORM *,int *,int *); -extern NCURSES_EXPORT(int) set_form_init (FORM *,Form_Hook); -extern NCURSES_EXPORT(int) set_form_term (FORM *,Form_Hook); -extern NCURSES_EXPORT(int) set_field_init (FORM *,Form_Hook); -extern NCURSES_EXPORT(int) set_field_term (FORM *,Form_Hook); -extern NCURSES_EXPORT(int) post_form (FORM *); -extern NCURSES_EXPORT(int) unpost_form (FORM *); -extern NCURSES_EXPORT(int) pos_form_cursor (FORM *); -extern NCURSES_EXPORT(int) form_driver (FORM *,int); -extern NCURSES_EXPORT(int) set_form_userptr (FORM *,void *); -extern NCURSES_EXPORT(int) set_form_opts (FORM *,Form_Options); -extern NCURSES_EXPORT(int) form_opts_on (FORM *,Form_Options); -extern NCURSES_EXPORT(int) form_opts_off (FORM *,Form_Options); -extern NCURSES_EXPORT(int) form_request_by_name (const char *); - -extern NCURSES_EXPORT(const char *) form_request_name (int); - -extern NCURSES_EXPORT(void *) form_userptr (const FORM *); - -extern NCURSES_EXPORT(Form_Options) form_opts (const FORM *); - -extern NCURSES_EXPORT(bool) data_ahead (const FORM *); -extern NCURSES_EXPORT(bool) data_behind (const FORM *); - -#if NCURSES_SP_FUNCS -extern NCURSES_EXPORT(FORM *) NCURSES_SP_NAME(new_form) (SCREEN*, FIELD **); -#endif - -#ifdef __cplusplus - } -#endif - -#endif /* FORM_H */ diff --git a/windows/ncurses/include/ncurses/menu.h b/windows/ncurses/include/ncurses/menu.h deleted file mode 100644 index 48eaa3f1d..000000000 --- a/windows/ncurses/include/ncurses/menu.h +++ /dev/null @@ -1,260 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2007,2009 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Juergen Pfeifer, 1995,1997 * - ****************************************************************************/ - -/* $Id: menu.h,v 1.20 2009/04/05 00:28:07 tom Exp $ */ - -#ifndef ETI_MENU -#define ETI_MENU - -#ifdef AMIGA -#define TEXT TEXT_ncurses -#endif - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef int Menu_Options; -typedef int Item_Options; - -/* Menu options: */ -#define O_ONEVALUE (0x01) -#define O_SHOWDESC (0x02) -#define O_ROWMAJOR (0x04) -#define O_IGNORECASE (0x08) -#define O_SHOWMATCH (0x10) -#define O_NONCYCLIC (0x20) - -/* Item options: */ -#define O_SELECTABLE (0x01) - -typedef struct -{ - const char* str; - unsigned short length; -} TEXT; - -typedef struct tagITEM -{ - TEXT name; /* name of menu item */ - TEXT description; /* description of item, optional in display */ - struct tagMENU *imenu; /* Pointer to parent menu */ - void *userptr; /* Pointer to user defined per item data */ - Item_Options opt; /* Item options */ - short index; /* Item number if connected to a menu */ - short y; /* y and x location of item in menu */ - short x; - bool value; /* Selection value */ - - struct tagITEM *left; /* neighbor items */ - struct tagITEM *right; - struct tagITEM *up; - struct tagITEM *down; - -} ITEM; - -typedef void (*Menu_Hook)(struct tagMENU *); - -typedef struct tagMENU -{ - short height; /* Nr. of chars high */ - short width; /* Nr. of chars wide */ - short rows; /* Nr. of items high */ - short cols; /* Nr. of items wide */ - short frows; /* Nr. of formatted items high */ - short fcols; /* Nr. of formatted items wide */ - short arows; /* Nr. of items high (actual) */ - short namelen; /* Max. name length */ - short desclen; /* Max. description length */ - short marklen; /* Length of mark, if any */ - short itemlen; /* Length of one item */ - short spc_desc; /* Spacing for descriptor */ - short spc_cols; /* Spacing for columns */ - short spc_rows; /* Spacing for rows */ - char *pattern; /* Buffer to store match chars */ - short pindex; /* Index into pattern buffer */ - WINDOW *win; /* Window containing menu */ - WINDOW *sub; /* Subwindow for menu display */ - WINDOW *userwin; /* User's window */ - WINDOW *usersub; /* User's subwindow */ - ITEM **items; /* array of items */ - short nitems; /* Nr. of items in menu */ - ITEM *curitem; /* Current item */ - short toprow; /* Top row of menu */ - chtype fore; /* Selection attribute */ - chtype back; /* Nonselection attribute */ - chtype grey; /* Inactive attribute */ - unsigned char pad; /* Pad character */ - - Menu_Hook menuinit; /* User hooks */ - Menu_Hook menuterm; - Menu_Hook iteminit; - Menu_Hook itemterm; - - void *userptr; /* Pointer to menus user data */ - char *mark; /* Pointer to marker string */ - - Menu_Options opt; /* Menu options */ - unsigned short status; /* Internal state of menu */ - -} MENU; - - -/* Define keys */ - -#define REQ_LEFT_ITEM (KEY_MAX + 1) -#define REQ_RIGHT_ITEM (KEY_MAX + 2) -#define REQ_UP_ITEM (KEY_MAX + 3) -#define REQ_DOWN_ITEM (KEY_MAX + 4) -#define REQ_SCR_ULINE (KEY_MAX + 5) -#define REQ_SCR_DLINE (KEY_MAX + 6) -#define REQ_SCR_DPAGE (KEY_MAX + 7) -#define REQ_SCR_UPAGE (KEY_MAX + 8) -#define REQ_FIRST_ITEM (KEY_MAX + 9) -#define REQ_LAST_ITEM (KEY_MAX + 10) -#define REQ_NEXT_ITEM (KEY_MAX + 11) -#define REQ_PREV_ITEM (KEY_MAX + 12) -#define REQ_TOGGLE_ITEM (KEY_MAX + 13) -#define REQ_CLEAR_PATTERN (KEY_MAX + 14) -#define REQ_BACK_PATTERN (KEY_MAX + 15) -#define REQ_NEXT_MATCH (KEY_MAX + 16) -#define REQ_PREV_MATCH (KEY_MAX + 17) - -#define MIN_MENU_COMMAND (KEY_MAX + 1) -#define MAX_MENU_COMMAND (KEY_MAX + 17) - -/* - * Some AT&T code expects MAX_COMMAND to be out-of-band not - * just for menu commands but for forms ones as well. - */ -#if defined(MAX_COMMAND) -# if (MAX_MENU_COMMAND > MAX_COMMAND) -# error Something is wrong -- MAX_MENU_COMMAND is greater than MAX_COMMAND -# elif (MAX_COMMAND != (KEY_MAX + 128)) -# error Something is wrong -- MAX_COMMAND is already inconsistently defined. -# endif -#else -# define MAX_COMMAND (KEY_MAX + 128) -#endif - - -/* --------- prototypes for libmenu functions ----------------------------- */ - -extern NCURSES_EXPORT(ITEM **) menu_items (const MENU *); -extern NCURSES_EXPORT(ITEM *) current_item (const MENU *); -extern NCURSES_EXPORT(ITEM *) new_item (const char *,const char *); - -extern NCURSES_EXPORT(MENU *) new_menu (ITEM **); - -extern NCURSES_EXPORT(Item_Options) item_opts (const ITEM *); -extern NCURSES_EXPORT(Menu_Options) menu_opts (const MENU *); - -extern NCURSES_EXPORT(Menu_Hook) item_init (const MENU *); -extern NCURSES_EXPORT(Menu_Hook) item_term (const MENU *); -extern NCURSES_EXPORT(Menu_Hook) menu_init (const MENU *); -extern NCURSES_EXPORT(Menu_Hook) menu_term (const MENU *); - -extern NCURSES_EXPORT(WINDOW *) menu_sub (const MENU *); -extern NCURSES_EXPORT(WINDOW *) menu_win (const MENU *); - -extern NCURSES_EXPORT(const char *) item_description (const ITEM *); -extern NCURSES_EXPORT(const char *) item_name (const ITEM *); -extern NCURSES_EXPORT(const char *) menu_mark (const MENU *); -extern NCURSES_EXPORT(const char *) menu_request_name (int); - -extern NCURSES_EXPORT(char *) menu_pattern (const MENU *); - -extern NCURSES_EXPORT(void *) menu_userptr (const MENU *); -extern NCURSES_EXPORT(void *) item_userptr (const ITEM *); - -extern NCURSES_EXPORT(chtype) menu_back (const MENU *); -extern NCURSES_EXPORT(chtype) menu_fore (const MENU *); -extern NCURSES_EXPORT(chtype) menu_grey (const MENU *); - -extern NCURSES_EXPORT(int) free_item (ITEM *); -extern NCURSES_EXPORT(int) free_menu (MENU *); -extern NCURSES_EXPORT(int) item_count (const MENU *); -extern NCURSES_EXPORT(int) item_index (const ITEM *); -extern NCURSES_EXPORT(int) item_opts_off (ITEM *,Item_Options); -extern NCURSES_EXPORT(int) item_opts_on (ITEM *,Item_Options); -extern NCURSES_EXPORT(int) menu_driver (MENU *,int); -extern NCURSES_EXPORT(int) menu_opts_off (MENU *,Menu_Options); -extern NCURSES_EXPORT(int) menu_opts_on (MENU *,Menu_Options); -extern NCURSES_EXPORT(int) menu_pad (const MENU *); -extern NCURSES_EXPORT(int) pos_menu_cursor (const MENU *); -extern NCURSES_EXPORT(int) post_menu (MENU *); -extern NCURSES_EXPORT(int) scale_menu (const MENU *,int *,int *); -extern NCURSES_EXPORT(int) set_current_item (MENU *menu,ITEM *item); -extern NCURSES_EXPORT(int) set_item_init (MENU *, Menu_Hook); -extern NCURSES_EXPORT(int) set_item_opts (ITEM *,Item_Options); -extern NCURSES_EXPORT(int) set_item_term (MENU *, Menu_Hook); -extern NCURSES_EXPORT(int) set_item_userptr (ITEM *, void *); -extern NCURSES_EXPORT(int) set_item_value (ITEM *,bool); -extern NCURSES_EXPORT(int) set_menu_back (MENU *,chtype); -extern NCURSES_EXPORT(int) set_menu_fore (MENU *,chtype); -extern NCURSES_EXPORT(int) set_menu_format (MENU *,int,int); -extern NCURSES_EXPORT(int) set_menu_grey (MENU *,chtype); -extern NCURSES_EXPORT(int) set_menu_init (MENU *, Menu_Hook); -extern NCURSES_EXPORT(int) set_menu_items (MENU *,ITEM **); -extern NCURSES_EXPORT(int) set_menu_mark (MENU *, const char *); -extern NCURSES_EXPORT(int) set_menu_opts (MENU *,Menu_Options); -extern NCURSES_EXPORT(int) set_menu_pad (MENU *,int); -extern NCURSES_EXPORT(int) set_menu_pattern (MENU *,const char *); -extern NCURSES_EXPORT(int) set_menu_sub (MENU *,WINDOW *); -extern NCURSES_EXPORT(int) set_menu_term (MENU *, Menu_Hook); -extern NCURSES_EXPORT(int) set_menu_userptr (MENU *,void *); -extern NCURSES_EXPORT(int) set_menu_win (MENU *,WINDOW *); -extern NCURSES_EXPORT(int) set_top_row (MENU *,int); -extern NCURSES_EXPORT(int) top_row (const MENU *); -extern NCURSES_EXPORT(int) unpost_menu (MENU *); -extern NCURSES_EXPORT(int) menu_request_by_name (const char *); -extern NCURSES_EXPORT(int) set_menu_spacing (MENU *,int,int,int); -extern NCURSES_EXPORT(int) menu_spacing (const MENU *,int *,int *,int *); - - -extern NCURSES_EXPORT(bool) item_value (const ITEM *); -extern NCURSES_EXPORT(bool) item_visible (const ITEM *); - -extern NCURSES_EXPORT(void) menu_format (const MENU *,int *,int *); - -#if NCURSES_SP_FUNCS -extern NCURSES_EXPORT(MENU *) NCURSES_SP_NAME(new_menu) (SCREEN*, ITEM **); -#endif - -#ifdef __cplusplus - } -#endif - -#endif /* ETI_MENU */ diff --git a/windows/ncurses/include/ncurses/nc_tparm.h b/windows/ncurses/include/ncurses/nc_tparm.h deleted file mode 100644 index a8dbcacb1..000000000 --- a/windows/ncurses/include/ncurses/nc_tparm.h +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** - * Copyright (c) 2006,2010 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Thomas E. Dickey 2006 * - ****************************************************************************/ - -/* $Id: nc_tparm.h,v 1.5 2010/12/25 20:27:22 tom Exp $ */ - -#ifndef NC_TPARM_included -#define NC_TPARM_included 1 - -/* - * Cast parameters past the formatting-string for tparm() to match the - * assumption of the varargs code. - */ -#ifndef TPARM_ARG -#define TPARM_ARG long -#endif - -#define TPARM_N(n) (TPARM_ARG)(n) - -#define TPARM_9(a,b,c,d,e,f,g,h,i,j) tparm(a,TPARM_N(b),TPARM_N(c),TPARM_N(d),TPARM_N(e),TPARM_N(f),TPARM_N(g),TPARM_N(h),TPARM_N(i),TPARM_N(j)) - -#if NCURSES_TPARM_VARARGS -#define TPARM_8(a,b,c,d,e,f,g,h,i) tparm(a,TPARM_N(b),TPARM_N(c),TPARM_N(d),TPARM_N(e),TPARM_N(f),TPARM_N(g),TPARM_N(h),TPARM_N(i)) -#define TPARM_7(a,b,c,d,e,f,g,h) tparm(a,TPARM_N(b),TPARM_N(c),TPARM_N(d),TPARM_N(e),TPARM_N(f),TPARM_N(g),TPARM_N(h)) -#define TPARM_6(a,b,c,d,e,f,g) tparm(a,TPARM_N(b),TPARM_N(c),TPARM_N(d),TPARM_N(e),TPARM_N(f),TPARM_N(g)) -#define TPARM_5(a,b,c,d,e,f) tparm(a,TPARM_N(b),TPARM_N(c),TPARM_N(d),TPARM_N(e),TPARM_N(f)) -#define TPARM_4(a,b,c,d,e) tparm(a,TPARM_N(b),TPARM_N(c),TPARM_N(d),TPARM_N(e)) -#define TPARM_3(a,b,c,d) tparm(a,TPARM_N(b),TPARM_N(c),TPARM_N(d)) -#define TPARM_2(a,b,c) tparm(a,TPARM_N(b),TPARM_N(c)) -#define TPARM_1(a,b) tparm(a,TPARM_N(b)) -#define TPARM_0(a) tparm(a) -#else -#define TPARM_8(a,b,c,d,e,f,g,h,i) TPARM_9(a,b,c,d,e,f,g,h,i,0) -#define TPARM_7(a,b,c,d,e,f,g,h) TPARM_8(a,b,c,d,e,f,g,h,0) -#define TPARM_6(a,b,c,d,e,f,g) TPARM_7(a,b,c,d,e,f,g,0) -#define TPARM_5(a,b,c,d,e,f) TPARM_6(a,b,c,d,e,f,0) -#define TPARM_4(a,b,c,d,e) TPARM_5(a,b,c,d,e,0) -#define TPARM_3(a,b,c,d) TPARM_4(a,b,c,d,0) -#define TPARM_2(a,b,c) TPARM_3(a,b,c,0) -#define TPARM_1(a,b) TPARM_2(a,b,0) -#define TPARM_1(a,b) TPARM_2(a,b,0) -#define TPARM_0(a) TPARM_1(a,0) -#endif - -#endif /* NC_TPARM_included */ diff --git a/windows/ncurses/include/ncurses/ncurses.h b/windows/ncurses/include/ncurses/ncurses.h deleted file mode 100644 index ff375d525..000000000 --- a/windows/ncurses/include/ncurses/ncurses.h +++ /dev/null @@ -1,1675 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2010,2011 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Zeyd M. Ben-Halim 1992,1995 * - * and: Eric S. Raymond * - * and: Thomas E. Dickey 1996-on * - ****************************************************************************/ - -/* $Id: curses.h.in,v 1.220 2011/01/22 19:47:20 tom Exp $ */ - -#ifndef __NCURSES_H -#define __NCURSES_H - -#define CURSES 1 -#define CURSES_H 1 - -/* These are defined only in curses.h, and are used for conditional compiles */ -#define NCURSES_VERSION_MAJOR 5 -#define NCURSES_VERSION_MINOR 9 -#define NCURSES_VERSION_PATCH 20110404 - -/* This is defined in more than one ncurses header, for identification */ -#undef NCURSES_VERSION -#define NCURSES_VERSION "5.9" - -/* - * Identify the mouse encoding version. - */ -#define NCURSES_MOUSE_VERSION 1 - -/* - * Definitions to facilitate DLL's. - */ -#include - -/* - * User-definable tweak to disable the include of . - */ -#ifndef NCURSES_ENABLE_STDBOOL_H -#define NCURSES_ENABLE_STDBOOL_H 1 -#endif - -/* - * NCURSES_ATTR_T is used to quiet compiler warnings when building ncurses - * configured using --disable-macros. - */ -#ifdef NCURSES_NOMACROS -#ifndef NCURSES_ATTR_T -#define NCURSES_ATTR_T attr_t -#endif -#endif /* NCURSES_NOMACROS */ - -#ifndef NCURSES_ATTR_T -#define NCURSES_ATTR_T int -#endif - -/* - * Expands to 'const' if ncurses is configured using --enable-const. Note that - * doing so makes it incompatible with other implementations of X/Open Curses. - */ -#undef NCURSES_CONST -#define NCURSES_CONST /*nothing*/ - -#undef NCURSES_INLINE -#define NCURSES_INLINE inline - -/* - * The internal type used for color values - */ -#undef NCURSES_COLOR_T -#define NCURSES_COLOR_T short - -/* - * Definition used to make WINDOW and similar structs opaque. - */ -#ifndef NCURSES_OPAQUE -#define NCURSES_OPAQUE 0 -#endif - -/* - * The reentrant code relies on the opaque setting, but adds features. - */ -#ifndef NCURSES_REENTRANT -#define NCURSES_REENTRANT 0 -#endif - -/* - * Control whether bindings for interop support are added. - */ -#undef NCURSES_INTEROP_FUNCS -#define NCURSES_INTEROP_FUNCS 0 - -/* - * The internal type used for window dimensions. - */ -#undef NCURSES_SIZE_T -#define NCURSES_SIZE_T short - -/* - * Control whether tparm() supports varargs or fixed-parameter list. - */ -#undef NCURSES_TPARM_VARARGS -#define NCURSES_TPARM_VARARGS 1 - -/* - * NCURSES_CH_T is used in building the library, but not used otherwise in - * this header file, since that would make the normal/wide-character versions - * of the header incompatible. - */ -#undef NCURSES_CH_T -#define NCURSES_CH_T chtype - -#if 0 && defined(_LP64) -typedef unsigned chtype; -typedef unsigned mmask_t; -#else -typedef unsigned long chtype; -typedef unsigned long mmask_t; -#endif - -/* - * We need FILE, etc. Include this before checking any feature symbols. - */ -#include - -/* - * With XPG4, you must define _XOPEN_SOURCE_EXTENDED, it is redundant (or - * conflicting) when _XOPEN_SOURCE is 500 or greater. - */ -#undef NCURSES_WIDECHAR -#if defined(_XOPEN_SOURCE_EXTENDED) || defined(_XPG5) -#define NCURSES_WIDECHAR -#endif - -#include /* we need va_list */ -#ifdef NCURSES_WIDECHAR -#include /* we want wchar_t */ -#endif - -/* X/Open and SVr4 specify that curses implements 'bool'. However, C++ may also - * implement it. If so, we must use the C++ compiler's type to avoid conflict - * with other interfaces. - * - * A further complication is that may declare 'bool' to be a - * different type, such as an enum which is not necessarily compatible with - * C++. If we have , make 'bool' a macro, so users may #undef it. - * Otherwise, let it remain a typedef to avoid conflicts with other #define's. - * In either case, make a typedef for NCURSES_BOOL which can be used if needed - * from either C or C++. - */ - -#undef TRUE -#define TRUE 1 - -#undef FALSE -#define FALSE 0 - -typedef unsigned char NCURSES_BOOL; - -#if defined(__cplusplus) /* __cplusplus, etc. */ - -/* use the C++ compiler's bool type */ -#define NCURSES_BOOL bool - -#else /* c89, c99, etc. */ - -#if NCURSES_ENABLE_STDBOOL_H -#include -/* use whatever the C compiler decides bool really is */ -#define NCURSES_BOOL bool -#else -/* there is no predefined bool - use our own */ -#undef bool -#define bool NCURSES_BOOL -#endif - -#endif /* !__cplusplus, etc. */ - -#ifdef __cplusplus -extern "C" { -#define NCURSES_CAST(type,value) static_cast(value) -#else -#define NCURSES_CAST(type,value) (type)(value) -#endif - -/* - * X/Open attributes. In the ncurses implementation, they are identical to the - * A_ attributes. - */ -#define WA_ATTRIBUTES A_ATTRIBUTES -#define WA_NORMAL A_NORMAL -#define WA_STANDOUT A_STANDOUT -#define WA_UNDERLINE A_UNDERLINE -#define WA_REVERSE A_REVERSE -#define WA_BLINK A_BLINK -#define WA_DIM A_DIM -#define WA_BOLD A_BOLD -#define WA_ALTCHARSET A_ALTCHARSET -#define WA_INVIS A_INVIS -#define WA_PROTECT A_PROTECT -#define WA_HORIZONTAL A_HORIZONTAL -#define WA_LEFT A_LEFT -#define WA_LOW A_LOW -#define WA_RIGHT A_RIGHT -#define WA_TOP A_TOP -#define WA_VERTICAL A_VERTICAL - -/* colors */ -#define COLOR_BLACK 0 -#define COLOR_RED 1 -#define COLOR_GREEN 2 -#define COLOR_YELLOW 3 -#define COLOR_BLUE 4 -#define COLOR_MAGENTA 5 -#define COLOR_CYAN 6 -#define COLOR_WHITE 7 - -/* line graphics */ - -#if 0 || NCURSES_REENTRANT -NCURSES_WRAPPED_VAR(chtype*, acs_map); -#define acs_map NCURSES_PUBLIC_VAR(acs_map()) -#else -extern NCURSES_EXPORT_VAR(chtype) acs_map[]; -#endif - -#define NCURSES_ACS(c) (acs_map[NCURSES_CAST(unsigned char,c)]) - -/* VT100 symbols begin here */ -#define ACS_ULCORNER NCURSES_ACS('l') /* upper left corner */ -#define ACS_LLCORNER NCURSES_ACS('m') /* lower left corner */ -#define ACS_URCORNER NCURSES_ACS('k') /* upper right corner */ -#define ACS_LRCORNER NCURSES_ACS('j') /* lower right corner */ -#define ACS_LTEE NCURSES_ACS('t') /* tee pointing right */ -#define ACS_RTEE NCURSES_ACS('u') /* tee pointing left */ -#define ACS_BTEE NCURSES_ACS('v') /* tee pointing up */ -#define ACS_TTEE NCURSES_ACS('w') /* tee pointing down */ -#define ACS_HLINE NCURSES_ACS('q') /* horizontal line */ -#define ACS_VLINE NCURSES_ACS('x') /* vertical line */ -#define ACS_PLUS NCURSES_ACS('n') /* large plus or crossover */ -#define ACS_S1 NCURSES_ACS('o') /* scan line 1 */ -#define ACS_S9 NCURSES_ACS('s') /* scan line 9 */ -#define ACS_DIAMOND NCURSES_ACS('`') /* diamond */ -#define ACS_CKBOARD NCURSES_ACS('a') /* checker board (stipple) */ -#define ACS_DEGREE NCURSES_ACS('f') /* degree symbol */ -#define ACS_PLMINUS NCURSES_ACS('g') /* plus/minus */ -#define ACS_BULLET NCURSES_ACS('~') /* bullet */ -/* Teletype 5410v1 symbols begin here */ -#define ACS_LARROW NCURSES_ACS(',') /* arrow pointing left */ -#define ACS_RARROW NCURSES_ACS('+') /* arrow pointing right */ -#define ACS_DARROW NCURSES_ACS('.') /* arrow pointing down */ -#define ACS_UARROW NCURSES_ACS('-') /* arrow pointing up */ -#define ACS_BOARD NCURSES_ACS('h') /* board of squares */ -#define ACS_LANTERN NCURSES_ACS('i') /* lantern symbol */ -#define ACS_BLOCK NCURSES_ACS('0') /* solid square block */ -/* - * These aren't documented, but a lot of System Vs have them anyway - * (you can spot pprryyzz{{||}} in a lot of AT&T terminfo strings). - * The ACS_names may not match AT&T's, our source didn't know them. - */ -#define ACS_S3 NCURSES_ACS('p') /* scan line 3 */ -#define ACS_S7 NCURSES_ACS('r') /* scan line 7 */ -#define ACS_LEQUAL NCURSES_ACS('y') /* less/equal */ -#define ACS_GEQUAL NCURSES_ACS('z') /* greater/equal */ -#define ACS_PI NCURSES_ACS('{') /* Pi */ -#define ACS_NEQUAL NCURSES_ACS('|') /* not equal */ -#define ACS_STERLING NCURSES_ACS('}') /* UK pound sign */ - -/* - * Line drawing ACS names are of the form ACS_trbl, where t is the top, r - * is the right, b is the bottom, and l is the left. t, r, b, and l might - * be B (blank), S (single), D (double), or T (thick). The subset defined - * here only uses B and S. - */ -#define ACS_BSSB ACS_ULCORNER -#define ACS_SSBB ACS_LLCORNER -#define ACS_BBSS ACS_URCORNER -#define ACS_SBBS ACS_LRCORNER -#define ACS_SBSS ACS_RTEE -#define ACS_SSSB ACS_LTEE -#define ACS_SSBS ACS_BTEE -#define ACS_BSSS ACS_TTEE -#define ACS_BSBS ACS_HLINE -#define ACS_SBSB ACS_VLINE -#define ACS_SSSS ACS_PLUS - -#undef ERR -#define ERR (-1) - -#undef OK -#define OK (0) - -/* values for the _flags member */ -#define _SUBWIN 0x01 /* is this a sub-window? */ -#define _ENDLINE 0x02 /* is the window flush right? */ -#define _FULLWIN 0x04 /* is the window full-screen? */ -#define _SCROLLWIN 0x08 /* bottom edge is at screen bottom? */ -#define _ISPAD 0x10 /* is this window a pad? */ -#define _HASMOVED 0x20 /* has cursor moved since last refresh? */ -#define _WRAPPED 0x40 /* cursor was just wrappped */ - -/* - * this value is used in the firstchar and lastchar fields to mark - * unchanged lines - */ -#define _NOCHANGE -1 - -/* - * this value is used in the oldindex field to mark lines created by insertions - * and scrolls. - */ -#define _NEWINDEX -1 - -typedef struct screen SCREEN; -typedef struct _win_st WINDOW; - -typedef chtype attr_t; /* ...must be at least as wide as chtype */ - -#ifdef NCURSES_WIDECHAR - -#if 0 -#ifdef mblen /* libutf8.h defines it w/o undefining first */ -#undef mblen -#endif -#include -#endif - -#if 0 -#include /* ...to get mbstate_t, etc. */ -#endif - -#if 0 -typedef unsigned short wchar_t; -#endif - -#if 0 -typedef unsigned int wint_t; -#endif - -/* - * cchar_t stores an array of CCHARW_MAX wide characters. The first is - * normally a spacing character. The others are non-spacing. If those - * (spacing and nonspacing) do not fill the array, a null L'\0' follows. - * Otherwise, a null is assumed to follow when extracting via getcchar(). - */ -#define CCHARW_MAX 5 -typedef struct -{ - attr_t attr; - wchar_t chars[CCHARW_MAX]; -#if 0 -#undef NCURSES_EXT_COLORS -#define NCURSES_EXT_COLORS 20110404 - int ext_color; /* color pair, must be more than 16-bits */ -#endif -} -cchar_t; - -#endif /* NCURSES_WIDECHAR */ - -#if !NCURSES_OPAQUE -struct ldat; - -struct _win_st -{ - NCURSES_SIZE_T _cury, _curx; /* current cursor position */ - - /* window location and size */ - NCURSES_SIZE_T _maxy, _maxx; /* maximums of x and y, NOT window size */ - NCURSES_SIZE_T _begy, _begx; /* screen coords of upper-left-hand corner */ - - short _flags; /* window state flags */ - - /* attribute tracking */ - attr_t _attrs; /* current attribute for non-space character */ - chtype _bkgd; /* current background char/attribute pair */ - - /* option values set by user */ - bool _notimeout; /* no time out on function-key entry? */ - bool _clear; /* consider all data in the window invalid? */ - bool _leaveok; /* OK to not reset cursor on exit? */ - bool _scroll; /* OK to scroll this window? */ - bool _idlok; /* OK to use insert/delete line? */ - bool _idcok; /* OK to use insert/delete char? */ - bool _immed; /* window in immed mode? (not yet used) */ - bool _sync; /* window in sync mode? */ - bool _use_keypad; /* process function keys into KEY_ symbols? */ - int _delay; /* 0 = nodelay, <0 = blocking, >0 = delay */ - - struct ldat *_line; /* the actual line data */ - - /* global screen state */ - NCURSES_SIZE_T _regtop; /* top line of scrolling region */ - NCURSES_SIZE_T _regbottom; /* bottom line of scrolling region */ - - /* these are used only if this is a sub-window */ - int _parx; /* x coordinate of this window in parent */ - int _pary; /* y coordinate of this window in parent */ - WINDOW *_parent; /* pointer to parent if a sub-window */ - - /* these are used only if this is a pad */ - struct pdat - { - NCURSES_SIZE_T _pad_y, _pad_x; - NCURSES_SIZE_T _pad_top, _pad_left; - NCURSES_SIZE_T _pad_bottom, _pad_right; - } _pad; - - NCURSES_SIZE_T _yoffset; /* real begy is _begy + _yoffset */ - -#ifdef NCURSES_WIDECHAR - cchar_t _bkgrnd; /* current background char/attribute pair */ -#if 0 - int _color; /* current color-pair for non-space character */ -#endif -#endif -}; -#endif /* NCURSES_OPAQUE */ - -/* - * This is an extension to support events... - */ -#if 1 -#ifdef NCURSES_WGETCH_EVENTS -#if !defined(__BEOS__) || defined(__HAIKU__) - /* Fix _nc_timed_wait() on BEOS... */ -# define NCURSES_EVENT_VERSION 1 -#endif /* !defined(__BEOS__) */ - -/* - * Bits to set in _nc_event.data.flags - */ -# define _NC_EVENT_TIMEOUT_MSEC 1 -# define _NC_EVENT_FILE 2 -# define _NC_EVENT_FILE_READABLE 2 -# if 0 /* Not supported yet... */ -# define _NC_EVENT_FILE_WRITABLE 4 -# define _NC_EVENT_FILE_EXCEPTION 8 -# endif - -typedef struct -{ - int type; - union - { - long timeout_msec; /* _NC_EVENT_TIMEOUT_MSEC */ - struct - { - unsigned int flags; - int fd; - unsigned int result; - } fev; /* _NC_EVENT_FILE */ - } data; -} _nc_event; - -typedef struct -{ - int count; - int result_flags; /* _NC_EVENT_TIMEOUT_MSEC or _NC_EVENT_FILE_READABLE */ - _nc_event *events[1]; -} _nc_eventlist; - -extern NCURSES_EXPORT(int) wgetch_events (WINDOW *, _nc_eventlist *); /* experimental */ -extern NCURSES_EXPORT(int) wgetnstr_events (WINDOW *,char *,int,_nc_eventlist *);/* experimental */ - -#endif /* NCURSES_WGETCH_EVENTS */ -#endif /* NCURSES_EXT_FUNCS */ - -/* - * GCC (and some other compilers) define '__attribute__'; we're using this - * macro to alert the compiler to flag inconsistencies in printf/scanf-like - * function calls. Just in case '__attribute__' isn't defined, make a dummy. - * Old versions of G++ do not accept it anyway, at least not consistently with - * GCC. - */ -#if !(defined(__GNUC__) || defined(__GNUG__) || defined(__attribute__)) -#define __attribute__(p) /* nothing */ -#endif - -/* - * We cannot define these in ncurses_cfg.h, since they require parameters to be - * passed (that is non-portable). If you happen to be using gcc with warnings - * enabled, define - * GCC_PRINTF - * GCC_SCANF - * to improve checking of calls to printw(), etc. - */ -#ifndef GCC_PRINTFLIKE -#if defined(GCC_PRINTF) && !defined(printf) -#define GCC_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var))) -#else -#define GCC_PRINTFLIKE(fmt,var) /*nothing*/ -#endif -#endif - -#ifndef GCC_SCANFLIKE -#if defined(GCC_SCANF) && !defined(scanf) -#define GCC_SCANFLIKE(fmt,var) __attribute__((format(scanf,fmt,var))) -#else -#define GCC_SCANFLIKE(fmt,var) /*nothing*/ -#endif -#endif - -#ifndef GCC_NORETURN -#define GCC_NORETURN /* nothing */ -#endif - -#ifndef GCC_UNUSED -#define GCC_UNUSED /* nothing */ -#endif - -/* - * Curses uses a helper function. Define our type for this to simplify - * extending it for the sp-funcs feature. - */ -typedef int (*NCURSES_OUTC)(int); - -/* - * Function prototypes. This is the complete X/Open Curses list of required - * functions. Those marked `generated' will have sources generated from the - * macro definitions later in this file, in order to satisfy XPG4.2 - * requirements. - */ - -extern NCURSES_EXPORT(int) addch (const chtype); /* generated */ -extern NCURSES_EXPORT(int) addchnstr (const chtype *, int); /* generated */ -extern NCURSES_EXPORT(int) addchstr (const chtype *); /* generated */ -extern NCURSES_EXPORT(int) addnstr (const char *, int); /* generated */ -extern NCURSES_EXPORT(int) addstr (const char *); /* generated */ -extern NCURSES_EXPORT(int) attroff (NCURSES_ATTR_T); /* generated */ -extern NCURSES_EXPORT(int) attron (NCURSES_ATTR_T); /* generated */ -extern NCURSES_EXPORT(int) attrset (NCURSES_ATTR_T); /* generated */ -extern NCURSES_EXPORT(int) attr_get (attr_t *, short *, void *); /* generated */ -extern NCURSES_EXPORT(int) attr_off (attr_t, void *); /* generated */ -extern NCURSES_EXPORT(int) attr_on (attr_t, void *); /* generated */ -extern NCURSES_EXPORT(int) attr_set (attr_t, short, void *); /* generated */ -extern NCURSES_EXPORT(int) baudrate (void); /* implemented */ -extern NCURSES_EXPORT(int) beep (void); /* implemented */ -extern NCURSES_EXPORT(int) bkgd (chtype); /* generated */ -extern NCURSES_EXPORT(void) bkgdset (chtype); /* generated */ -extern NCURSES_EXPORT(int) border (chtype,chtype,chtype,chtype,chtype,chtype,chtype,chtype); /* generated */ -extern NCURSES_EXPORT(int) box (WINDOW *, chtype, chtype); /* generated */ -extern NCURSES_EXPORT(bool) can_change_color (void); /* implemented */ -extern NCURSES_EXPORT(int) cbreak (void); /* implemented */ -extern NCURSES_EXPORT(int) chgat (int, attr_t, short, const void *); /* generated */ -extern NCURSES_EXPORT(int) clear (void); /* generated */ -extern NCURSES_EXPORT(int) clearok (WINDOW *,bool); /* implemented */ -extern NCURSES_EXPORT(int) clrtobot (void); /* generated */ -extern NCURSES_EXPORT(int) clrtoeol (void); /* generated */ -extern NCURSES_EXPORT(int) color_content (short,short*,short*,short*); /* implemented */ -extern NCURSES_EXPORT(int) color_set (short,void*); /* generated */ -extern NCURSES_EXPORT(int) COLOR_PAIR (int); /* generated */ -extern NCURSES_EXPORT(int) copywin (const WINDOW*,WINDOW*,int,int,int,int,int,int,int); /* implemented */ -extern NCURSES_EXPORT(int) curs_set (int); /* implemented */ -extern NCURSES_EXPORT(int) def_prog_mode (void); /* implemented */ -extern NCURSES_EXPORT(int) def_shell_mode (void); /* implemented */ -extern NCURSES_EXPORT(int) delay_output (int); /* implemented */ -extern NCURSES_EXPORT(int) delch (void); /* generated */ -extern NCURSES_EXPORT(void) delscreen (SCREEN *); /* implemented */ -extern NCURSES_EXPORT(int) delwin (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) deleteln (void); /* generated */ -extern NCURSES_EXPORT(WINDOW *) derwin (WINDOW *,int,int,int,int); /* implemented */ -extern NCURSES_EXPORT(int) doupdate (void); /* implemented */ -extern NCURSES_EXPORT(WINDOW *) dupwin (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) echo (void); /* implemented */ -extern NCURSES_EXPORT(int) echochar (const chtype); /* generated */ -extern NCURSES_EXPORT(int) erase (void); /* generated */ -extern NCURSES_EXPORT(int) endwin (void); /* implemented */ -extern NCURSES_EXPORT(char) erasechar (void); /* implemented */ -extern NCURSES_EXPORT(void) filter (void); /* implemented */ -extern NCURSES_EXPORT(int) flash (void); /* implemented */ -extern NCURSES_EXPORT(int) flushinp (void); /* implemented */ -extern NCURSES_EXPORT(chtype) getbkgd (WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) getch (void); /* generated */ -extern NCURSES_EXPORT(int) getnstr (char *, int); /* generated */ -extern NCURSES_EXPORT(int) getstr (char *); /* generated */ -extern NCURSES_EXPORT(WINDOW *) getwin (FILE *); /* implemented */ -extern NCURSES_EXPORT(int) halfdelay (int); /* implemented */ -extern NCURSES_EXPORT(bool) has_colors (void); /* implemented */ -extern NCURSES_EXPORT(bool) has_ic (void); /* implemented */ -extern NCURSES_EXPORT(bool) has_il (void); /* implemented */ -extern NCURSES_EXPORT(int) hline (chtype, int); /* generated */ -extern NCURSES_EXPORT(void) idcok (WINDOW *, bool); /* implemented */ -extern NCURSES_EXPORT(int) idlok (WINDOW *, bool); /* implemented */ -extern NCURSES_EXPORT(void) immedok (WINDOW *, bool); /* implemented */ -extern NCURSES_EXPORT(chtype) inch (void); /* generated */ -extern NCURSES_EXPORT(int) inchnstr (chtype *, int); /* generated */ -extern NCURSES_EXPORT(int) inchstr (chtype *); /* generated */ -extern NCURSES_EXPORT(WINDOW *) initscr (void); /* implemented */ -extern NCURSES_EXPORT(int) init_color (short,short,short,short); /* implemented */ -extern NCURSES_EXPORT(int) init_pair (short,short,short); /* implemented */ -extern NCURSES_EXPORT(int) innstr (char *, int); /* generated */ -extern NCURSES_EXPORT(int) insch (chtype); /* generated */ -extern NCURSES_EXPORT(int) insdelln (int); /* generated */ -extern NCURSES_EXPORT(int) insertln (void); /* generated */ -extern NCURSES_EXPORT(int) insnstr (const char *, int); /* generated */ -extern NCURSES_EXPORT(int) insstr (const char *); /* generated */ -extern NCURSES_EXPORT(int) instr (char *); /* generated */ -extern NCURSES_EXPORT(int) intrflush (WINDOW *,bool); /* implemented */ -extern NCURSES_EXPORT(bool) isendwin (void); /* implemented */ -extern NCURSES_EXPORT(bool) is_linetouched (WINDOW *,int); /* implemented */ -extern NCURSES_EXPORT(bool) is_wintouched (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(NCURSES_CONST char *) keyname (int); /* implemented */ -extern NCURSES_EXPORT(int) keypad (WINDOW *,bool); /* implemented */ -extern NCURSES_EXPORT(char) killchar (void); /* implemented */ -extern NCURSES_EXPORT(int) leaveok (WINDOW *,bool); /* implemented */ -extern NCURSES_EXPORT(char *) longname (void); /* implemented */ -extern NCURSES_EXPORT(int) meta (WINDOW *,bool); /* implemented */ -extern NCURSES_EXPORT(int) move (int, int); /* generated */ -extern NCURSES_EXPORT(int) mvaddch (int, int, const chtype); /* generated */ -extern NCURSES_EXPORT(int) mvaddchnstr (int, int, const chtype *, int); /* generated */ -extern NCURSES_EXPORT(int) mvaddchstr (int, int, const chtype *); /* generated */ -extern NCURSES_EXPORT(int) mvaddnstr (int, int, const char *, int); /* generated */ -extern NCURSES_EXPORT(int) mvaddstr (int, int, const char *); /* generated */ -extern NCURSES_EXPORT(int) mvchgat (int, int, int, attr_t, short, const void *); /* generated */ -extern NCURSES_EXPORT(int) mvcur (int,int,int,int); /* implemented */ -extern NCURSES_EXPORT(int) mvdelch (int, int); /* generated */ -extern NCURSES_EXPORT(int) mvderwin (WINDOW *, int, int); /* implemented */ -extern NCURSES_EXPORT(int) mvgetch (int, int); /* generated */ -extern NCURSES_EXPORT(int) mvgetnstr (int, int, char *, int); /* generated */ -extern NCURSES_EXPORT(int) mvgetstr (int, int, char *); /* generated */ -extern NCURSES_EXPORT(int) mvhline (int, int, chtype, int); /* generated */ -extern NCURSES_EXPORT(chtype) mvinch (int, int); /* generated */ -extern NCURSES_EXPORT(int) mvinchnstr (int, int, chtype *, int); /* generated */ -extern NCURSES_EXPORT(int) mvinchstr (int, int, chtype *); /* generated */ -extern NCURSES_EXPORT(int) mvinnstr (int, int, char *, int); /* generated */ -extern NCURSES_EXPORT(int) mvinsch (int, int, chtype); /* generated */ -extern NCURSES_EXPORT(int) mvinsnstr (int, int, const char *, int); /* generated */ -extern NCURSES_EXPORT(int) mvinsstr (int, int, const char *); /* generated */ -extern NCURSES_EXPORT(int) mvinstr (int, int, char *); /* generated */ -extern NCURSES_EXPORT(int) mvprintw (int,int, const char *,...) /* implemented */ - GCC_PRINTFLIKE(3,4); -extern NCURSES_EXPORT(int) mvscanw (int,int, NCURSES_CONST char *,...) /* implemented */ - GCC_SCANFLIKE(3,4); -extern NCURSES_EXPORT(int) mvvline (int, int, chtype, int); /* generated */ -extern NCURSES_EXPORT(int) mvwaddch (WINDOW *, int, int, const chtype); /* generated */ -extern NCURSES_EXPORT(int) mvwaddchnstr (WINDOW *, int, int, const chtype *, int);/* generated */ -extern NCURSES_EXPORT(int) mvwaddchstr (WINDOW *, int, int, const chtype *); /* generated */ -extern NCURSES_EXPORT(int) mvwaddnstr (WINDOW *, int, int, const char *, int); /* generated */ -extern NCURSES_EXPORT(int) mvwaddstr (WINDOW *, int, int, const char *); /* generated */ -extern NCURSES_EXPORT(int) mvwchgat (WINDOW *, int, int, int, attr_t, short, const void *);/* generated */ -extern NCURSES_EXPORT(int) mvwdelch (WINDOW *, int, int); /* generated */ -extern NCURSES_EXPORT(int) mvwgetch (WINDOW *, int, int); /* generated */ -extern NCURSES_EXPORT(int) mvwgetnstr (WINDOW *, int, int, char *, int); /* generated */ -extern NCURSES_EXPORT(int) mvwgetstr (WINDOW *, int, int, char *); /* generated */ -extern NCURSES_EXPORT(int) mvwhline (WINDOW *, int, int, chtype, int); /* generated */ -extern NCURSES_EXPORT(int) mvwin (WINDOW *,int,int); /* implemented */ -extern NCURSES_EXPORT(chtype) mvwinch (WINDOW *, int, int); /* generated */ -extern NCURSES_EXPORT(int) mvwinchnstr (WINDOW *, int, int, chtype *, int); /* generated */ -extern NCURSES_EXPORT(int) mvwinchstr (WINDOW *, int, int, chtype *); /* generated */ -extern NCURSES_EXPORT(int) mvwinnstr (WINDOW *, int, int, char *, int); /* generated */ -extern NCURSES_EXPORT(int) mvwinsch (WINDOW *, int, int, chtype); /* generated */ -extern NCURSES_EXPORT(int) mvwinsnstr (WINDOW *, int, int, const char *, int); /* generated */ -extern NCURSES_EXPORT(int) mvwinsstr (WINDOW *, int, int, const char *); /* generated */ -extern NCURSES_EXPORT(int) mvwinstr (WINDOW *, int, int, char *); /* generated */ -extern NCURSES_EXPORT(int) mvwprintw (WINDOW*,int,int, const char *,...) /* implemented */ - GCC_PRINTFLIKE(4,5); -extern NCURSES_EXPORT(int) mvwscanw (WINDOW *,int,int, NCURSES_CONST char *,...) /* implemented */ - GCC_SCANFLIKE(4,5); -extern NCURSES_EXPORT(int) mvwvline (WINDOW *,int, int, chtype, int); /* generated */ -extern NCURSES_EXPORT(int) napms (int); /* implemented */ -extern NCURSES_EXPORT(WINDOW *) newpad (int,int); /* implemented */ -extern NCURSES_EXPORT(SCREEN *) newterm (NCURSES_CONST char *,FILE *,FILE *); /* implemented */ -extern NCURSES_EXPORT(WINDOW *) newwin (int,int,int,int); /* implemented */ -extern NCURSES_EXPORT(int) nl (void); /* implemented */ -extern NCURSES_EXPORT(int) nocbreak (void); /* implemented */ -extern NCURSES_EXPORT(int) nodelay (WINDOW *,bool); /* implemented */ -extern NCURSES_EXPORT(int) noecho (void); /* implemented */ -extern NCURSES_EXPORT(int) nonl (void); /* implemented */ -extern NCURSES_EXPORT(void) noqiflush (void); /* implemented */ -extern NCURSES_EXPORT(int) noraw (void); /* implemented */ -extern NCURSES_EXPORT(int) notimeout (WINDOW *,bool); /* implemented */ -extern NCURSES_EXPORT(int) overlay (const WINDOW*,WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) overwrite (const WINDOW*,WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) pair_content (short,short*,short*); /* implemented */ -extern NCURSES_EXPORT(int) PAIR_NUMBER (int); /* generated */ -extern NCURSES_EXPORT(int) pechochar (WINDOW *, const chtype); /* implemented */ -extern NCURSES_EXPORT(int) pnoutrefresh (WINDOW*,int,int,int,int,int,int);/* implemented */ -extern NCURSES_EXPORT(int) prefresh (WINDOW *,int,int,int,int,int,int); /* implemented */ -extern NCURSES_EXPORT(int) printw (const char *,...) /* implemented */ - GCC_PRINTFLIKE(1,2); -extern NCURSES_EXPORT(int) putwin (WINDOW *, FILE *); /* implemented */ -extern NCURSES_EXPORT(void) qiflush (void); /* implemented */ -extern NCURSES_EXPORT(int) raw (void); /* implemented */ -extern NCURSES_EXPORT(int) redrawwin (WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) refresh (void); /* generated */ -extern NCURSES_EXPORT(int) resetty (void); /* implemented */ -extern NCURSES_EXPORT(int) reset_prog_mode (void); /* implemented */ -extern NCURSES_EXPORT(int) reset_shell_mode (void); /* implemented */ -extern NCURSES_EXPORT(int) ripoffline (int, int (*)(WINDOW *, int)); /* implemented */ -extern NCURSES_EXPORT(int) savetty (void); /* implemented */ -extern NCURSES_EXPORT(int) scanw (NCURSES_CONST char *,...) /* implemented */ - GCC_SCANFLIKE(1,2); -extern NCURSES_EXPORT(int) scr_dump (const char *); /* implemented */ -extern NCURSES_EXPORT(int) scr_init (const char *); /* implemented */ -extern NCURSES_EXPORT(int) scrl (int); /* generated */ -extern NCURSES_EXPORT(int) scroll (WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) scrollok (WINDOW *,bool); /* implemented */ -extern NCURSES_EXPORT(int) scr_restore (const char *); /* implemented */ -extern NCURSES_EXPORT(int) scr_set (const char *); /* implemented */ -extern NCURSES_EXPORT(int) setscrreg (int,int); /* generated */ -extern NCURSES_EXPORT(SCREEN *) set_term (SCREEN *); /* implemented */ -extern NCURSES_EXPORT(int) slk_attroff (const chtype); /* implemented */ -extern NCURSES_EXPORT(int) slk_attr_off (const attr_t, void *); /* generated:WIDEC */ -extern NCURSES_EXPORT(int) slk_attron (const chtype); /* implemented */ -extern NCURSES_EXPORT(int) slk_attr_on (attr_t,void*); /* generated:WIDEC */ -extern NCURSES_EXPORT(int) slk_attrset (const chtype); /* implemented */ -extern NCURSES_EXPORT(attr_t) slk_attr (void); /* implemented */ -extern NCURSES_EXPORT(int) slk_attr_set (const attr_t,short,void*); /* implemented */ -extern NCURSES_EXPORT(int) slk_clear (void); /* implemented */ -extern NCURSES_EXPORT(int) slk_color (short); /* implemented */ -extern NCURSES_EXPORT(int) slk_init (int); /* implemented */ -extern NCURSES_EXPORT(char *) slk_label (int); /* implemented */ -extern NCURSES_EXPORT(int) slk_noutrefresh (void); /* implemented */ -extern NCURSES_EXPORT(int) slk_refresh (void); /* implemented */ -extern NCURSES_EXPORT(int) slk_restore (void); /* implemented */ -extern NCURSES_EXPORT(int) slk_set (int,const char *,int); /* implemented */ -extern NCURSES_EXPORT(int) slk_touch (void); /* implemented */ -extern NCURSES_EXPORT(int) standout (void); /* generated */ -extern NCURSES_EXPORT(int) standend (void); /* generated */ -extern NCURSES_EXPORT(int) start_color (void); /* implemented */ -extern NCURSES_EXPORT(WINDOW *) subpad (WINDOW *, int, int, int, int); /* implemented */ -extern NCURSES_EXPORT(WINDOW *) subwin (WINDOW *, int, int, int, int); /* implemented */ -extern NCURSES_EXPORT(int) syncok (WINDOW *, bool); /* implemented */ -extern NCURSES_EXPORT(chtype) termattrs (void); /* implemented */ -extern NCURSES_EXPORT(char *) termname (void); /* implemented */ -extern NCURSES_EXPORT(void) timeout (int); /* generated */ -extern NCURSES_EXPORT(int) touchline (WINDOW *, int, int); /* generated */ -extern NCURSES_EXPORT(int) touchwin (WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) typeahead (int); /* implemented */ -extern NCURSES_EXPORT(int) ungetch (int); /* implemented */ -extern NCURSES_EXPORT(int) untouchwin (WINDOW *); /* generated */ -extern NCURSES_EXPORT(void) use_env (bool); /* implemented */ -extern NCURSES_EXPORT(int) vidattr (chtype); /* implemented */ -extern NCURSES_EXPORT(int) vidputs (chtype, NCURSES_OUTC); /* implemented */ -extern NCURSES_EXPORT(int) vline (chtype, int); /* generated */ -extern NCURSES_EXPORT(int) vwprintw (WINDOW *, const char *,va_list); /* implemented */ -extern NCURSES_EXPORT(int) vw_printw (WINDOW *, const char *,va_list); /* generated */ -extern NCURSES_EXPORT(int) vwscanw (WINDOW *, NCURSES_CONST char *,va_list); /* implemented */ -extern NCURSES_EXPORT(int) vw_scanw (WINDOW *, NCURSES_CONST char *,va_list); /* generated */ -extern NCURSES_EXPORT(int) waddch (WINDOW *, const chtype); /* implemented */ -extern NCURSES_EXPORT(int) waddchnstr (WINDOW *,const chtype *,int); /* implemented */ -extern NCURSES_EXPORT(int) waddchstr (WINDOW *,const chtype *); /* generated */ -extern NCURSES_EXPORT(int) waddnstr (WINDOW *,const char *,int); /* implemented */ -extern NCURSES_EXPORT(int) waddstr (WINDOW *,const char *); /* generated */ -extern NCURSES_EXPORT(int) wattron (WINDOW *, int); /* generated */ -extern NCURSES_EXPORT(int) wattroff (WINDOW *, int); /* generated */ -extern NCURSES_EXPORT(int) wattrset (WINDOW *, int); /* generated */ -extern NCURSES_EXPORT(int) wattr_get (WINDOW *, attr_t *, short *, void *); /* generated */ -extern NCURSES_EXPORT(int) wattr_on (WINDOW *, attr_t, void *); /* implemented */ -extern NCURSES_EXPORT(int) wattr_off (WINDOW *, attr_t, void *); /* implemented */ -extern NCURSES_EXPORT(int) wattr_set (WINDOW *, attr_t, short, void *); /* generated */ -extern NCURSES_EXPORT(int) wbkgd (WINDOW *, chtype); /* implemented */ -extern NCURSES_EXPORT(void) wbkgdset (WINDOW *,chtype); /* implemented */ -extern NCURSES_EXPORT(int) wborder (WINDOW *,chtype,chtype,chtype,chtype,chtype,chtype,chtype,chtype); /* implemented */ -extern NCURSES_EXPORT(int) wchgat (WINDOW *, int, attr_t, short, const void *);/* implemented */ -extern NCURSES_EXPORT(int) wclear (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) wclrtobot (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) wclrtoeol (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) wcolor_set (WINDOW*,short,void*); /* implemented */ -extern NCURSES_EXPORT(void) wcursyncup (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) wdelch (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) wdeleteln (WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) wechochar (WINDOW *, const chtype); /* implemented */ -extern NCURSES_EXPORT(int) werase (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) wgetch (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) wgetnstr (WINDOW *,char *,int); /* implemented */ -extern NCURSES_EXPORT(int) wgetstr (WINDOW *, char *); /* generated */ -extern NCURSES_EXPORT(int) whline (WINDOW *, chtype, int); /* implemented */ -extern NCURSES_EXPORT(chtype) winch (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) winchnstr (WINDOW *, chtype *, int); /* implemented */ -extern NCURSES_EXPORT(int) winchstr (WINDOW *, chtype *); /* generated */ -extern NCURSES_EXPORT(int) winnstr (WINDOW *, char *, int); /* implemented */ -extern NCURSES_EXPORT(int) winsch (WINDOW *, chtype); /* implemented */ -extern NCURSES_EXPORT(int) winsdelln (WINDOW *,int); /* implemented */ -extern NCURSES_EXPORT(int) winsertln (WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) winsnstr (WINDOW *, const char *,int); /* implemented */ -extern NCURSES_EXPORT(int) winsstr (WINDOW *, const char *); /* generated */ -extern NCURSES_EXPORT(int) winstr (WINDOW *, char *); /* generated */ -extern NCURSES_EXPORT(int) wmove (WINDOW *,int,int); /* implemented */ -extern NCURSES_EXPORT(int) wnoutrefresh (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) wprintw (WINDOW *, const char *,...) /* implemented */ - GCC_PRINTFLIKE(2,3); -extern NCURSES_EXPORT(int) wredrawln (WINDOW *,int,int); /* implemented */ -extern NCURSES_EXPORT(int) wrefresh (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(int) wscanw (WINDOW *, NCURSES_CONST char *,...) /* implemented */ - GCC_SCANFLIKE(2,3); -extern NCURSES_EXPORT(int) wscrl (WINDOW *,int); /* implemented */ -extern NCURSES_EXPORT(int) wsetscrreg (WINDOW *,int,int); /* implemented */ -extern NCURSES_EXPORT(int) wstandout (WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) wstandend (WINDOW *); /* generated */ -extern NCURSES_EXPORT(void) wsyncdown (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(void) wsyncup (WINDOW *); /* implemented */ -extern NCURSES_EXPORT(void) wtimeout (WINDOW *,int); /* implemented */ -extern NCURSES_EXPORT(int) wtouchln (WINDOW *,int,int,int); /* implemented */ -extern NCURSES_EXPORT(int) wvline (WINDOW *,chtype,int); /* implemented */ - -/* - * These are also declared in : - */ -extern NCURSES_EXPORT(int) tigetflag (NCURSES_CONST char *); /* implemented */ -extern NCURSES_EXPORT(int) tigetnum (NCURSES_CONST char *); /* implemented */ -extern NCURSES_EXPORT(char *) tigetstr (NCURSES_CONST char *); /* implemented */ -extern NCURSES_EXPORT(int) putp (const char *); /* implemented */ - -#if NCURSES_TPARM_VARARGS -extern NCURSES_EXPORT(char *) tparm (NCURSES_CONST char *, ...); /* special */ -#else -extern NCURSES_EXPORT(char *) tparm (NCURSES_CONST char *, long,long,long,long,long,long,long,long,long); /* special */ -extern NCURSES_EXPORT(char *) tparm_varargs (NCURSES_CONST char *, ...); /* special */ -#endif - -extern NCURSES_EXPORT(char *) tiparm (const char *, ...); /* special */ - -/* - * These functions are not in X/Open, but we use them in macro definitions: - */ -extern NCURSES_EXPORT(int) getattrs (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) getcurx (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) getcury (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) getbegx (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) getbegy (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) getmaxx (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) getmaxy (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) getparx (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) getpary (const WINDOW *); /* generated */ - -/* - * vid_attr() was implemented originally based on a draft of X/Open curses. - */ -#ifndef NCURSES_WIDECHAR -#define vid_attr(a,pair,opts) vidattr(a) -#endif - -/* - * These functions are extensions - not in X/Open Curses. - */ -#if 1 -#undef NCURSES_EXT_FUNCS -#define NCURSES_EXT_FUNCS 20110404 -typedef int (*NCURSES_WINDOW_CB)(WINDOW *, void *); -typedef int (*NCURSES_SCREEN_CB)(SCREEN *, void *); -extern NCURSES_EXPORT(bool) is_term_resized (int, int); -extern NCURSES_EXPORT(char *) keybound (int, int); -extern NCURSES_EXPORT(const char *) curses_version (void); -extern NCURSES_EXPORT(int) assume_default_colors (int, int); -extern NCURSES_EXPORT(int) define_key (const char *, int); -extern NCURSES_EXPORT(int) get_escdelay (void); -extern NCURSES_EXPORT(int) key_defined (const char *); -extern NCURSES_EXPORT(int) keyok (int, bool); -extern NCURSES_EXPORT(int) resize_term (int, int); -extern NCURSES_EXPORT(int) resizeterm (int, int); -extern NCURSES_EXPORT(int) set_escdelay (int); -extern NCURSES_EXPORT(int) set_tabsize (int); -extern NCURSES_EXPORT(int) use_default_colors (void); -extern NCURSES_EXPORT(int) use_extended_names (bool); -extern NCURSES_EXPORT(int) use_legacy_coding (int); -extern NCURSES_EXPORT(int) use_screen (SCREEN *, NCURSES_SCREEN_CB, void *); -extern NCURSES_EXPORT(int) use_window (WINDOW *, NCURSES_WINDOW_CB, void *); -extern NCURSES_EXPORT(int) wresize (WINDOW *, int, int); -extern NCURSES_EXPORT(void) nofilter(void); - -/* - * These extensions provide access to information stored in the WINDOW even - * when NCURSES_OPAQUE is set: - */ -extern NCURSES_EXPORT(WINDOW *) wgetparent (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_cleared (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_idcok (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_idlok (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_immedok (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_keypad (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_leaveok (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_nodelay (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_notimeout (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_pad (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_scrollok (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_subwin (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(bool) is_syncok (const WINDOW *); /* generated */ -extern NCURSES_EXPORT(int) wgetscrreg (const WINDOW *, int *, int *); /* generated */ - -#else -#define curses_version() NCURSES_VERSION -#endif - -/* - * Extra extension-functions, which pass a SCREEN pointer rather than using - * a global variable SP. - */ -#if 1 -#undef NCURSES_SP_FUNCS -#define NCURSES_SP_FUNCS 20110404 -#define NCURSES_SP_NAME(name) name##_sp - -/* Define the sp-funcs helper function */ -#define NCURSES_SP_OUTC NCURSES_SP_NAME(NCURSES_OUTC) -typedef int (*NCURSES_SP_OUTC)(SCREEN*, int); - -extern NCURSES_EXPORT(SCREEN *) new_prescr (void); /* implemented:SP_FUNC */ - -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(baudrate) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(beep) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(bool) NCURSES_SP_NAME(can_change_color) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(cbreak) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(curs_set) (SCREEN*, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(color_content) (SCREEN*, short, short*, short*, short*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(def_prog_mode) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(def_shell_mode) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(delay_output) (SCREEN*, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(doupdate) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(echo) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(endwin) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(char) NCURSES_SP_NAME(erasechar) (SCREEN*);/* implemented:SP_FUNC */ -extern NCURSES_EXPORT(void) NCURSES_SP_NAME(filter) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(flash) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(flushinp) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(WINDOW *) NCURSES_SP_NAME(getwin) (SCREEN*, FILE *); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(halfdelay) (SCREEN*, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(bool) NCURSES_SP_NAME(has_colors) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(bool) NCURSES_SP_NAME(has_ic) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(bool) NCURSES_SP_NAME(has_il) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(init_color) (SCREEN*, short, short, short, short); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(init_pair) (SCREEN*, short, short, short); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(intrflush) (SCREEN*, WINDOW*, bool); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(bool) NCURSES_SP_NAME(isendwin) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(NCURSES_CONST char *) NCURSES_SP_NAME(keyname) (SCREEN*, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(char) NCURSES_SP_NAME(killchar) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(char *) NCURSES_SP_NAME(longname) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(mvcur) (SCREEN*, int, int, int, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(napms) (SCREEN*, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(WINDOW *) NCURSES_SP_NAME(newpad) (SCREEN*, int, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(SCREEN *) NCURSES_SP_NAME(newterm) (SCREEN*, NCURSES_CONST char *, FILE *, FILE *); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(WINDOW *) NCURSES_SP_NAME(newwin) (SCREEN*, int, int, int, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(nl) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(nocbreak) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(noecho) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(nonl) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(void) NCURSES_SP_NAME(noqiflush) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(noraw) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(pair_content) (SCREEN*, short, short*, short*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(void) NCURSES_SP_NAME(qiflush) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(raw) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(reset_prog_mode) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(reset_shell_mode) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(resetty) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(ripoffline) (SCREEN*, int, int (*)(WINDOW *, int)); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(savetty) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(scr_init) (SCREEN*, const char *); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(scr_restore) (SCREEN*, const char *); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(scr_set) (SCREEN*, const char *); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_attroff) (SCREEN*, const chtype); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_attron) (SCREEN*, const chtype); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_attrset) (SCREEN*, const chtype); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(attr_t) NCURSES_SP_NAME(slk_attr) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_attr_set) (SCREEN*, const attr_t, short, void*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_clear) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_color) (SCREEN*, short); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_init) (SCREEN*, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(char *) NCURSES_SP_NAME(slk_label) (SCREEN*, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_noutrefresh) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_refresh) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_restore) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_set) (SCREEN*, int, const char *, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(slk_touch) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(start_color) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(chtype) NCURSES_SP_NAME(termattrs) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(char *) NCURSES_SP_NAME(termname) (SCREEN*); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(typeahead) (SCREEN*, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(ungetch) (SCREEN*, int); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(void) NCURSES_SP_NAME(use_env) (SCREEN*, bool); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(vidattr) (SCREEN*, chtype); /* implemented:SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(vidputs) (SCREEN*, chtype, NCURSES_SP_OUTC); /* implemented:SP_FUNC */ -#if 1 -extern NCURSES_EXPORT(char *) NCURSES_SP_NAME(keybound) (SCREEN*, int, int); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(assume_default_colors) (SCREEN*, int, int); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(define_key) (SCREEN*, const char *, int); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(get_escdelay) (SCREEN*); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(bool) NCURSES_SP_NAME(is_term_resized) (SCREEN*, int, int); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(key_defined) (SCREEN*, const char *); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(keyok) (SCREEN*, int, bool); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(void) NCURSES_SP_NAME(nofilter) (SCREEN*); /* implemented */ /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(resize_term) (SCREEN*, int, int); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(resizeterm) (SCREEN*, int, int); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(set_escdelay) (SCREEN*, int); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(set_tabsize) (SCREEN*, int); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(use_default_colors) (SCREEN*); /* implemented:EXT_SP_FUNC */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(use_legacy_coding) (SCREEN*, int); /* implemented:EXT_SP_FUNC */ -#endif -#else -#undef NCURSES_SP_FUNCS -#define NCURSES_SP_FUNCS 0 -#define NCURSES_SP_NAME(name) name -#define NCURSES_SP_OUTC NCURSES_OUTC -#endif - -/* attributes */ - -#define NCURSES_ATTR_SHIFT 8 -#define NCURSES_BITS(mask,shift) ((mask) << ((shift) + NCURSES_ATTR_SHIFT)) - -#define A_NORMAL (1UL - 1UL) -#define A_ATTRIBUTES NCURSES_BITS(~(1UL - 1UL),0) -#define A_CHARTEXT (NCURSES_BITS(1UL,0) - 1UL) -#define A_COLOR NCURSES_BITS(((1UL) << 8) - 1UL,0) -#define A_STANDOUT NCURSES_BITS(1UL,8) -#define A_UNDERLINE NCURSES_BITS(1UL,9) -#define A_REVERSE NCURSES_BITS(1UL,10) -#define A_BLINK NCURSES_BITS(1UL,11) -#define A_DIM NCURSES_BITS(1UL,12) -#define A_BOLD NCURSES_BITS(1UL,13) -#define A_ALTCHARSET NCURSES_BITS(1UL,14) -#define A_INVIS NCURSES_BITS(1UL,15) -#define A_PROTECT NCURSES_BITS(1UL,16) -#define A_HORIZONTAL NCURSES_BITS(1UL,17) -#define A_LEFT NCURSES_BITS(1UL,18) -#define A_LOW NCURSES_BITS(1UL,19) -#define A_RIGHT NCURSES_BITS(1UL,20) -#define A_TOP NCURSES_BITS(1UL,21) -#define A_VERTICAL NCURSES_BITS(1UL,22) - -/* - * Most of the pseudo functions are macros that either provide compatibility - * with older versions of curses, or provide inline functionality to improve - * performance. - */ - -/* - * These pseudo functions are always implemented as macros: - */ - -#define getyx(win,y,x) (y = getcury(win), x = getcurx(win)) -#define getbegyx(win,y,x) (y = getbegy(win), x = getbegx(win)) -#define getmaxyx(win,y,x) (y = getmaxy(win), x = getmaxx(win)) -#define getparyx(win,y,x) (y = getpary(win), x = getparx(win)) - -#define getsyx(y,x) do { if (newscr) { \ - if (is_leaveok(newscr)) \ - (y) = (x) = -1; \ - else \ - getyx(newscr,(y), (x)); \ - } \ - } while(0) - -#define setsyx(y,x) do { if (newscr) { \ - if ((y) == -1 && (x) == -1) \ - leaveok(newscr, TRUE); \ - else { \ - leaveok(newscr, FALSE); \ - wmove(newscr, (y), (x)); \ - } \ - } \ - } while(0) - -#ifndef NCURSES_NOMACROS - -/* - * These miscellaneous pseudo functions are provided for compatibility: - */ - -#define wgetstr(w, s) wgetnstr(w, s, -1) -#define getnstr(s, n) wgetnstr(stdscr, s, n) - -#define setterm(term) setupterm(term, 1, (int *)0) - -#define fixterm() reset_prog_mode() -#define resetterm() reset_shell_mode() -#define saveterm() def_prog_mode() -#define crmode() cbreak() -#define nocrmode() nocbreak() -#define gettmode() - -/* It seems older SYSV curses versions define these */ -#if !NCURSES_OPAQUE -#define getattrs(win) NCURSES_CAST(int, (win) ? (win)->_attrs : A_NORMAL) -#define getcurx(win) ((win) ? (win)->_curx : ERR) -#define getcury(win) ((win) ? (win)->_cury : ERR) -#define getbegx(win) ((win) ? (win)->_begx : ERR) -#define getbegy(win) ((win) ? (win)->_begy : ERR) -#define getmaxx(win) ((win) ? ((win)->_maxx + 1) : ERR) -#define getmaxy(win) ((win) ? ((win)->_maxy + 1) : ERR) -#define getparx(win) ((win) ? (win)->_parx : ERR) -#define getpary(win) ((win) ? (win)->_pary : ERR) -#endif /* NCURSES_OPAQUE */ - -#define wstandout(win) (wattrset(win,A_STANDOUT)) -#define wstandend(win) (wattrset(win,A_NORMAL)) - -#define wattron(win,at) wattr_on(win, NCURSES_CAST(attr_t, at), NULL) -#define wattroff(win,at) wattr_off(win, NCURSES_CAST(attr_t, at), NULL) - -#if !NCURSES_OPAQUE -#if defined(NCURSES_WIDECHAR) && 0 -#define wattrset(win,at) ((win) \ - ? ((win)->_color = PAIR_NUMBER(at), \ - (win)->_attrs = NCURSES_CAST(attr_t, at), \ - OK) \ - : ERR) -#else -#define wattrset(win,at) ((win) \ - ? ((win)->_attrs = NCURSES_CAST(attr_t, at), \ - OK) \ - : ERR) -#endif -#endif /* NCURSES_OPAQUE */ - -#define scroll(win) wscrl(win,1) - -#define touchwin(win) wtouchln((win), 0, getmaxy(win), 1) -#define touchline(win, s, c) wtouchln((win), s, c, 1) -#define untouchwin(win) wtouchln((win), 0, getmaxy(win), 0) - -#define box(win, v, h) wborder(win, v, v, h, h, 0, 0, 0, 0) -#define border(ls, rs, ts, bs, tl, tr, bl, br) wborder(stdscr, ls, rs, ts, bs, tl, tr, bl, br) -#define hline(ch, n) whline(stdscr, ch, n) -#define vline(ch, n) wvline(stdscr, ch, n) - -#define winstr(w, s) winnstr(w, s, -1) -#define winchstr(w, s) winchnstr(w, s, -1) -#define winsstr(w, s) winsnstr(w, s, -1) - -#if !NCURSES_OPAQUE -#define redrawwin(win) wredrawln(win, 0, (win)->_maxy+1) -#endif /* NCURSES_OPAQUE */ - -#define waddstr(win,str) waddnstr(win,str,-1) -#define waddchstr(win,str) waddchnstr(win,str,-1) - -/* - * These apply to the first 256 color pairs. - */ -#define COLOR_PAIR(n) NCURSES_BITS(n, 0) -#define PAIR_NUMBER(a) (NCURSES_CAST(int,((NCURSES_CAST(unsigned long,a) & A_COLOR) >> NCURSES_ATTR_SHIFT))) - -/* - * pseudo functions for standard screen - */ - -#define addch(ch) waddch(stdscr,ch) -#define addchnstr(str,n) waddchnstr(stdscr,str,n) -#define addchstr(str) waddchstr(stdscr,str) -#define addnstr(str,n) waddnstr(stdscr,str,n) -#define addstr(str) waddnstr(stdscr,str,-1) -#define attroff(at) wattroff(stdscr,at) -#define attron(at) wattron(stdscr,at) -#define attrset(at) wattrset(stdscr,at) -#define attr_get(ap,cp,o) wattr_get(stdscr,ap,cp,o) -#define attr_off(a,o) wattr_off(stdscr,a,o) -#define attr_on(a,o) wattr_on(stdscr,a,o) -#define attr_set(a,c,o) wattr_set(stdscr,a,c,o) -#define bkgd(ch) wbkgd(stdscr,ch) -#define bkgdset(ch) wbkgdset(stdscr,ch) -#define chgat(n,a,c,o) wchgat(stdscr,n,a,c,o) -#define clear() wclear(stdscr) -#define clrtobot() wclrtobot(stdscr) -#define clrtoeol() wclrtoeol(stdscr) -#define color_set(c,o) wcolor_set(stdscr,c,o) -#define delch() wdelch(stdscr) -#define deleteln() winsdelln(stdscr,-1) -#define echochar(c) wechochar(stdscr,c) -#define erase() werase(stdscr) -#define getch() wgetch(stdscr) -#define getstr(str) wgetstr(stdscr,str) -#define inch() winch(stdscr) -#define inchnstr(s,n) winchnstr(stdscr,s,n) -#define inchstr(s) winchstr(stdscr,s) -#define innstr(s,n) winnstr(stdscr,s,n) -#define insch(c) winsch(stdscr,c) -#define insdelln(n) winsdelln(stdscr,n) -#define insertln() winsdelln(stdscr,1) -#define insnstr(s,n) winsnstr(stdscr,s,n) -#define insstr(s) winsstr(stdscr,s) -#define instr(s) winstr(stdscr,s) -#define move(y,x) wmove(stdscr,y,x) -#define refresh() wrefresh(stdscr) -#define scrl(n) wscrl(stdscr,n) -#define setscrreg(t,b) wsetscrreg(stdscr,t,b) -#define standend() wstandend(stdscr) -#define standout() wstandout(stdscr) -#define timeout(delay) wtimeout(stdscr,delay) -#define wdeleteln(win) winsdelln(win,-1) -#define winsertln(win) winsdelln(win,1) - -/* - * mv functions - */ - -#define mvwaddch(win,y,x,ch) (wmove(win,y,x) == ERR ? ERR : waddch(win,ch)) -#define mvwaddchnstr(win,y,x,str,n) (wmove(win,y,x) == ERR ? ERR : waddchnstr(win,str,n)) -#define mvwaddchstr(win,y,x,str) (wmove(win,y,x) == ERR ? ERR : waddchnstr(win,str,-1)) -#define mvwaddnstr(win,y,x,str,n) (wmove(win,y,x) == ERR ? ERR : waddnstr(win,str,n)) -#define mvwaddstr(win,y,x,str) (wmove(win,y,x) == ERR ? ERR : waddnstr(win,str,-1)) -#define mvwdelch(win,y,x) (wmove(win,y,x) == ERR ? ERR : wdelch(win)) -#define mvwchgat(win,y,x,n,a,c,o) (wmove(win,y,x) == ERR ? ERR : wchgat(win,n,a,c,o)) -#define mvwgetch(win,y,x) (wmove(win,y,x) == ERR ? ERR : wgetch(win)) -#define mvwgetnstr(win,y,x,str,n) (wmove(win,y,x) == ERR ? ERR : wgetnstr(win,str,n)) -#define mvwgetstr(win,y,x,str) (wmove(win,y,x) == ERR ? ERR : wgetstr(win,str)) -#define mvwhline(win,y,x,c,n) (wmove(win,y,x) == ERR ? ERR : whline(win,c,n)) -#define mvwinch(win,y,x) (wmove(win,y,x) == ERR ? NCURSES_CAST(chtype, ERR) : winch(win)) -#define mvwinchnstr(win,y,x,s,n) (wmove(win,y,x) == ERR ? ERR : winchnstr(win,s,n)) -#define mvwinchstr(win,y,x,s) (wmove(win,y,x) == ERR ? ERR : winchstr(win,s)) -#define mvwinnstr(win,y,x,s,n) (wmove(win,y,x) == ERR ? ERR : winnstr(win,s,n)) -#define mvwinsch(win,y,x,c) (wmove(win,y,x) == ERR ? ERR : winsch(win,c)) -#define mvwinsnstr(win,y,x,s,n) (wmove(win,y,x) == ERR ? ERR : winsnstr(win,s,n)) -#define mvwinsstr(win,y,x,s) (wmove(win,y,x) == ERR ? ERR : winsstr(win,s)) -#define mvwinstr(win,y,x,s) (wmove(win,y,x) == ERR ? ERR : winstr(win,s)) -#define mvwvline(win,y,x,c,n) (wmove(win,y,x) == ERR ? ERR : wvline(win,c,n)) - -#define mvaddch(y,x,ch) mvwaddch(stdscr,y,x,ch) -#define mvaddchnstr(y,x,str,n) mvwaddchnstr(stdscr,y,x,str,n) -#define mvaddchstr(y,x,str) mvwaddchstr(stdscr,y,x,str) -#define mvaddnstr(y,x,str,n) mvwaddnstr(stdscr,y,x,str,n) -#define mvaddstr(y,x,str) mvwaddstr(stdscr,y,x,str) -#define mvchgat(y,x,n,a,c,o) mvwchgat(stdscr,y,x,n,a,c,o) -#define mvdelch(y,x) mvwdelch(stdscr,y,x) -#define mvgetch(y,x) mvwgetch(stdscr,y,x) -#define mvgetnstr(y,x,str,n) mvwgetnstr(stdscr,y,x,str,n) -#define mvgetstr(y,x,str) mvwgetstr(stdscr,y,x,str) -#define mvhline(y,x,c,n) mvwhline(stdscr,y,x,c,n) -#define mvinch(y,x) mvwinch(stdscr,y,x) -#define mvinchnstr(y,x,s,n) mvwinchnstr(stdscr,y,x,s,n) -#define mvinchstr(y,x,s) mvwinchstr(stdscr,y,x,s) -#define mvinnstr(y,x,s,n) mvwinnstr(stdscr,y,x,s,n) -#define mvinsch(y,x,c) mvwinsch(stdscr,y,x,c) -#define mvinsnstr(y,x,s,n) mvwinsnstr(stdscr,y,x,s,n) -#define mvinsstr(y,x,s) mvwinsstr(stdscr,y,x,s) -#define mvinstr(y,x,s) mvwinstr(stdscr,y,x,s) -#define mvvline(y,x,c,n) mvwvline(stdscr,y,x,c,n) - -/* - * Some wide-character functions can be implemented without the extensions. - */ -#if !NCURSES_OPAQUE -#define getbkgd(win) ((win)->_bkgd) -#endif /* NCURSES_OPAQUE */ - -#define slk_attr_off(a,v) ((v) ? ERR : slk_attroff(a)) -#define slk_attr_on(a,v) ((v) ? ERR : slk_attron(a)) - -#if !NCURSES_OPAQUE -#if defined(NCURSES_WIDECHAR) && 0 -#define wattr_set(win,a,p,opts) ((win)->_attrs = ((a) & ~A_COLOR), \ - (win)->_color = (p), \ - OK) -#define wattr_get(win,a,p,opts) ((void)((a) != (void *)0 && (*(a) = (win)->_attrs)), \ - (void)((p) != (void *)0 && (*(p) = (short)(win)->_color)), \ - OK) -#else -#define wattr_set(win,a,p,opts) ((win)->_attrs = (((a) & ~A_COLOR) | (attr_t)COLOR_PAIR(p)), OK) -#define wattr_get(win,a,p,opts) ((void)((a) != (void *)0 && (*(a) = (win)->_attrs)), \ - (void)((p) != (void *)0 && (*(p) = (short)PAIR_NUMBER((win)->_attrs))), \ - OK) -#endif -#endif /* NCURSES_OPAQUE */ - -/* - * X/Open curses deprecates SVr4 vwprintw/vwscanw, which are supposed to use - * varargs.h. It adds new calls vw_printw/vw_scanw, which are supposed to - * use POSIX stdarg.h. The ncurses versions of vwprintw/vwscanw already - * use stdarg.h, so... - */ -#define vw_printw vwprintw -#define vw_scanw vwscanw - -/* - * Export fallback function for use in C++ binding. - */ -#if !1 -#define vsscanf(a,b,c) _nc_vsscanf(a,b,c) -NCURSES_EXPORT(int) vsscanf(const char *, const char *, va_list); -#endif - -/* - * These macros are extensions - not in X/Open Curses. - */ -#if 1 -#if !NCURSES_OPAQUE -#define is_cleared(win) ((win) ? (win)->_clear : FALSE) -#define is_idcok(win) ((win) ? (win)->_idcok : FALSE) -#define is_idlok(win) ((win) ? (win)->_idlok : FALSE) -#define is_immedok(win) ((win) ? (win)->_immed : FALSE) -#define is_keypad(win) ((win) ? (win)->_use_keypad : FALSE) -#define is_leaveok(win) ((win) ? (win)->_leaveok : FALSE) -#define is_nodelay(win) ((win) ? ((win)->_delay == 0) : FALSE) -#define is_notimeout(win) ((win) ? (win)->_notimeout : FALSE) -#define is_pad(win) ((win) ? ((win)->_flags & _ISPAD) != 0 : FALSE) -#define is_scrollok(win) ((win) ? (win)->_scroll : FALSE) -#define is_subwin(win) ((win) ? ((win)->_flags & _SUBWIN) != 0 : FALSE) -#define is_syncok(win) ((win) ? (win)->_sync : FALSE) -#define wgetparent(win) ((win) ? (win)->_parent : 0) -#define wgetscrreg(win,t,b) ((win) ? (*(t) = (win)->_regtop, *(b) = (win)->_regbottom, OK) : ERR) -#endif -#endif - -#endif /* NCURSES_NOMACROS */ - -/* - * Public variables. - * - * Notes: - * a. ESCDELAY was an undocumented feature under AIX curses. - * It gives the ESC expire time in milliseconds. - * b. ttytype is needed for backward compatibility - */ -#if NCURSES_REENTRANT - -NCURSES_WRAPPED_VAR(WINDOW *, curscr); -NCURSES_WRAPPED_VAR(WINDOW *, newscr); -NCURSES_WRAPPED_VAR(WINDOW *, stdscr); -NCURSES_WRAPPED_VAR(char *, ttytype); -NCURSES_WRAPPED_VAR(int, COLORS); -NCURSES_WRAPPED_VAR(int, COLOR_PAIRS); -NCURSES_WRAPPED_VAR(int, COLS); -NCURSES_WRAPPED_VAR(int, ESCDELAY); -NCURSES_WRAPPED_VAR(int, LINES); -NCURSES_WRAPPED_VAR(int, TABSIZE); - -#define curscr NCURSES_PUBLIC_VAR(curscr()) -#define newscr NCURSES_PUBLIC_VAR(newscr()) -#define stdscr NCURSES_PUBLIC_VAR(stdscr()) -#define ttytype NCURSES_PUBLIC_VAR(ttytype()) -#define COLORS NCURSES_PUBLIC_VAR(COLORS()) -#define COLOR_PAIRS NCURSES_PUBLIC_VAR(COLOR_PAIRS()) -#define COLS NCURSES_PUBLIC_VAR(COLS()) -#define ESCDELAY NCURSES_PUBLIC_VAR(ESCDELAY()) -#define LINES NCURSES_PUBLIC_VAR(LINES()) -#define TABSIZE NCURSES_PUBLIC_VAR(TABSIZE()) - -#else - -extern NCURSES_EXPORT_VAR(WINDOW *) curscr; -extern NCURSES_EXPORT_VAR(WINDOW *) newscr; -extern NCURSES_EXPORT_VAR(WINDOW *) stdscr; -extern NCURSES_EXPORT_VAR(char) ttytype[]; -extern NCURSES_EXPORT_VAR(int) COLORS; -extern NCURSES_EXPORT_VAR(int) COLOR_PAIRS; -extern NCURSES_EXPORT_VAR(int) COLS; -extern NCURSES_EXPORT_VAR(int) ESCDELAY; -extern NCURSES_EXPORT_VAR(int) LINES; -extern NCURSES_EXPORT_VAR(int) TABSIZE; - -#endif - -/* - * Pseudo-character tokens outside ASCII range. The curses wgetch() function - * will return any given one of these only if the corresponding k- capability - * is defined in your terminal's terminfo entry. - * - * Some keys (KEY_A1, etc) are arranged like this: - * a1 up a3 - * left b2 right - * c1 down c3 - * - * A few key codes do not depend upon the terminfo entry. - */ -#define KEY_CODE_YES 0400 /* A wchar_t contains a key code */ -#define KEY_MIN 0401 /* Minimum curses key */ -#define KEY_BREAK 0401 /* Break key (unreliable) */ -#define KEY_SRESET 0530 /* Soft (partial) reset (unreliable) */ -#define KEY_RESET 0531 /* Reset or hard reset (unreliable) */ -/* - * These definitions were generated by ./MKkey_defs.sh ./Caps - */ -#define KEY_DOWN 0402 /* down-arrow key */ -#define KEY_UP 0403 /* up-arrow key */ -#define KEY_LEFT 0404 /* left-arrow key */ -#define KEY_RIGHT 0405 /* right-arrow key */ -#define KEY_HOME 0406 /* home key */ -#define KEY_BACKSPACE 0407 /* backspace key */ -#define KEY_F0 0410 /* Function keys. Space for 64 */ -#define KEY_F(n) (KEY_F0+(n)) /* Value of function key n */ -#define KEY_DL 0510 /* delete-line key */ -#define KEY_IL 0511 /* insert-line key */ -#define KEY_DC 0512 /* delete-character key */ -#define KEY_IC 0513 /* insert-character key */ -#define KEY_EIC 0514 /* sent by rmir or smir in insert mode */ -#define KEY_CLEAR 0515 /* clear-screen or erase key */ -#define KEY_EOS 0516 /* clear-to-end-of-screen key */ -#define KEY_EOL 0517 /* clear-to-end-of-line key */ -#define KEY_SF 0520 /* scroll-forward key */ -#define KEY_SR 0521 /* scroll-backward key */ -#define KEY_NPAGE 0522 /* next-page key */ -#define KEY_PPAGE 0523 /* previous-page key */ -#define KEY_STAB 0524 /* set-tab key */ -#define KEY_CTAB 0525 /* clear-tab key */ -#define KEY_CATAB 0526 /* clear-all-tabs key */ -#define KEY_ENTER 0527 /* enter/send key */ -#define KEY_PRINT 0532 /* print key */ -#define KEY_LL 0533 /* lower-left key (home down) */ -#define KEY_A1 0534 /* upper left of keypad */ -#define KEY_A3 0535 /* upper right of keypad */ -#define KEY_B2 0536 /* center of keypad */ -#define KEY_C1 0537 /* lower left of keypad */ -#define KEY_C3 0540 /* lower right of keypad */ -#define KEY_BTAB 0541 /* back-tab key */ -#define KEY_BEG 0542 /* begin key */ -#define KEY_CANCEL 0543 /* cancel key */ -#define KEY_CLOSE 0544 /* close key */ -#define KEY_COMMAND 0545 /* command key */ -#define KEY_COPY 0546 /* copy key */ -#define KEY_CREATE 0547 /* create key */ -#define KEY_END 0550 /* end key */ -#define KEY_EXIT 0551 /* exit key */ -#define KEY_FIND 0552 /* find key */ -#define KEY_HELP 0553 /* help key */ -#define KEY_MARK 0554 /* mark key */ -#define KEY_MESSAGE 0555 /* message key */ -#define KEY_MOVE 0556 /* move key */ -#define KEY_NEXT 0557 /* next key */ -#define KEY_OPEN 0560 /* open key */ -#define KEY_OPTIONS 0561 /* options key */ -#define KEY_PREVIOUS 0562 /* previous key */ -#define KEY_REDO 0563 /* redo key */ -#define KEY_REFERENCE 0564 /* reference key */ -#define KEY_REFRESH 0565 /* refresh key */ -#define KEY_REPLACE 0566 /* replace key */ -#define KEY_RESTART 0567 /* restart key */ -#define KEY_RESUME 0570 /* resume key */ -#define KEY_SAVE 0571 /* save key */ -#define KEY_SBEG 0572 /* shifted begin key */ -#define KEY_SCANCEL 0573 /* shifted cancel key */ -#define KEY_SCOMMAND 0574 /* shifted command key */ -#define KEY_SCOPY 0575 /* shifted copy key */ -#define KEY_SCREATE 0576 /* shifted create key */ -#define KEY_SDC 0577 /* shifted delete-character key */ -#define KEY_SDL 0600 /* shifted delete-line key */ -#define KEY_SELECT 0601 /* select key */ -#define KEY_SEND 0602 /* shifted end key */ -#define KEY_SEOL 0603 /* shifted clear-to-end-of-line key */ -#define KEY_SEXIT 0604 /* shifted exit key */ -#define KEY_SFIND 0605 /* shifted find key */ -#define KEY_SHELP 0606 /* shifted help key */ -#define KEY_SHOME 0607 /* shifted home key */ -#define KEY_SIC 0610 /* shifted insert-character key */ -#define KEY_SLEFT 0611 /* shifted left-arrow key */ -#define KEY_SMESSAGE 0612 /* shifted message key */ -#define KEY_SMOVE 0613 /* shifted move key */ -#define KEY_SNEXT 0614 /* shifted next key */ -#define KEY_SOPTIONS 0615 /* shifted options key */ -#define KEY_SPREVIOUS 0616 /* shifted previous key */ -#define KEY_SPRINT 0617 /* shifted print key */ -#define KEY_SREDO 0620 /* shifted redo key */ -#define KEY_SREPLACE 0621 /* shifted replace key */ -#define KEY_SRIGHT 0622 /* shifted right-arrow key */ -#define KEY_SRSUME 0623 /* shifted resume key */ -#define KEY_SSAVE 0624 /* shifted save key */ -#define KEY_SSUSPEND 0625 /* shifted suspend key */ -#define KEY_SUNDO 0626 /* shifted undo key */ -#define KEY_SUSPEND 0627 /* suspend key */ -#define KEY_UNDO 0630 /* undo key */ -#define KEY_MOUSE 0631 /* Mouse event has occurred */ -#define KEY_RESIZE 0632 /* Terminal resize event */ -#define KEY_EVENT 0633 /* We were interrupted by an event */ - -#define KEY_MAX 0777 /* Maximum key value is 0633 */ -/* $Id: curses.tail,v 1.20 2010/03/28 19:10:55 tom Exp $ */ -/* - * vile:cmode: - * This file is part of ncurses, designed to be appended after curses.h.in - * (see that file for the relevant copyright). - */ - -/* mouse interface */ - -#if NCURSES_MOUSE_VERSION > 1 -#define NCURSES_MOUSE_MASK(b,m) ((m) << (((b) - 1) * 5)) -#else -#define NCURSES_MOUSE_MASK(b,m) ((m) << (((b) - 1) * 6)) -#endif - -#define NCURSES_BUTTON_RELEASED 001L -#define NCURSES_BUTTON_PRESSED 002L -#define NCURSES_BUTTON_CLICKED 004L -#define NCURSES_DOUBLE_CLICKED 010L -#define NCURSES_TRIPLE_CLICKED 020L -#define NCURSES_RESERVED_EVENT 040L - -/* event masks */ -#define BUTTON1_RELEASED NCURSES_MOUSE_MASK(1, NCURSES_BUTTON_RELEASED) -#define BUTTON1_PRESSED NCURSES_MOUSE_MASK(1, NCURSES_BUTTON_PRESSED) -#define BUTTON1_CLICKED NCURSES_MOUSE_MASK(1, NCURSES_BUTTON_CLICKED) -#define BUTTON1_DOUBLE_CLICKED NCURSES_MOUSE_MASK(1, NCURSES_DOUBLE_CLICKED) -#define BUTTON1_TRIPLE_CLICKED NCURSES_MOUSE_MASK(1, NCURSES_TRIPLE_CLICKED) - -#define BUTTON2_RELEASED NCURSES_MOUSE_MASK(2, NCURSES_BUTTON_RELEASED) -#define BUTTON2_PRESSED NCURSES_MOUSE_MASK(2, NCURSES_BUTTON_PRESSED) -#define BUTTON2_CLICKED NCURSES_MOUSE_MASK(2, NCURSES_BUTTON_CLICKED) -#define BUTTON2_DOUBLE_CLICKED NCURSES_MOUSE_MASK(2, NCURSES_DOUBLE_CLICKED) -#define BUTTON2_TRIPLE_CLICKED NCURSES_MOUSE_MASK(2, NCURSES_TRIPLE_CLICKED) - -#define BUTTON3_RELEASED NCURSES_MOUSE_MASK(3, NCURSES_BUTTON_RELEASED) -#define BUTTON3_PRESSED NCURSES_MOUSE_MASK(3, NCURSES_BUTTON_PRESSED) -#define BUTTON3_CLICKED NCURSES_MOUSE_MASK(3, NCURSES_BUTTON_CLICKED) -#define BUTTON3_DOUBLE_CLICKED NCURSES_MOUSE_MASK(3, NCURSES_DOUBLE_CLICKED) -#define BUTTON3_TRIPLE_CLICKED NCURSES_MOUSE_MASK(3, NCURSES_TRIPLE_CLICKED) - -#define BUTTON4_RELEASED NCURSES_MOUSE_MASK(4, NCURSES_BUTTON_RELEASED) -#define BUTTON4_PRESSED NCURSES_MOUSE_MASK(4, NCURSES_BUTTON_PRESSED) -#define BUTTON4_CLICKED NCURSES_MOUSE_MASK(4, NCURSES_BUTTON_CLICKED) -#define BUTTON4_DOUBLE_CLICKED NCURSES_MOUSE_MASK(4, NCURSES_DOUBLE_CLICKED) -#define BUTTON4_TRIPLE_CLICKED NCURSES_MOUSE_MASK(4, NCURSES_TRIPLE_CLICKED) - -/* - * In 32 bits the version-1 scheme does not provide enough space for a 5th - * button, unless we choose to change the ABI by omitting the reserved-events. - */ -#if NCURSES_MOUSE_VERSION > 1 - -#define BUTTON5_RELEASED NCURSES_MOUSE_MASK(5, NCURSES_BUTTON_RELEASED) -#define BUTTON5_PRESSED NCURSES_MOUSE_MASK(5, NCURSES_BUTTON_PRESSED) -#define BUTTON5_CLICKED NCURSES_MOUSE_MASK(5, NCURSES_BUTTON_CLICKED) -#define BUTTON5_DOUBLE_CLICKED NCURSES_MOUSE_MASK(5, NCURSES_DOUBLE_CLICKED) -#define BUTTON5_TRIPLE_CLICKED NCURSES_MOUSE_MASK(5, NCURSES_TRIPLE_CLICKED) - -#define BUTTON_CTRL NCURSES_MOUSE_MASK(6, 0001L) -#define BUTTON_SHIFT NCURSES_MOUSE_MASK(6, 0002L) -#define BUTTON_ALT NCURSES_MOUSE_MASK(6, 0004L) -#define REPORT_MOUSE_POSITION NCURSES_MOUSE_MASK(6, 0010L) - -#else - -#define BUTTON1_RESERVED_EVENT NCURSES_MOUSE_MASK(1, NCURSES_RESERVED_EVENT) -#define BUTTON2_RESERVED_EVENT NCURSES_MOUSE_MASK(2, NCURSES_RESERVED_EVENT) -#define BUTTON3_RESERVED_EVENT NCURSES_MOUSE_MASK(3, NCURSES_RESERVED_EVENT) -#define BUTTON4_RESERVED_EVENT NCURSES_MOUSE_MASK(4, NCURSES_RESERVED_EVENT) - -#define BUTTON_CTRL NCURSES_MOUSE_MASK(5, 0001L) -#define BUTTON_SHIFT NCURSES_MOUSE_MASK(5, 0002L) -#define BUTTON_ALT NCURSES_MOUSE_MASK(5, 0004L) -#define REPORT_MOUSE_POSITION NCURSES_MOUSE_MASK(5, 0010L) - -#endif - -#define ALL_MOUSE_EVENTS (REPORT_MOUSE_POSITION - 1) - -/* macros to extract single event-bits from masks */ -#define BUTTON_RELEASE(e, x) ((e) & NCURSES_MOUSE_MASK(x, 001)) -#define BUTTON_PRESS(e, x) ((e) & NCURSES_MOUSE_MASK(x, 002)) -#define BUTTON_CLICK(e, x) ((e) & NCURSES_MOUSE_MASK(x, 004)) -#define BUTTON_DOUBLE_CLICK(e, x) ((e) & NCURSES_MOUSE_MASK(x, 010)) -#define BUTTON_TRIPLE_CLICK(e, x) ((e) & NCURSES_MOUSE_MASK(x, 020)) -#define BUTTON_RESERVED_EVENT(e, x) ((e) & NCURSES_MOUSE_MASK(x, 040)) - -typedef struct -{ - short id; /* ID to distinguish multiple devices */ - int x, y, z; /* event coordinates (character-cell) */ - mmask_t bstate; /* button state bits */ -} -MEVENT; - -extern NCURSES_EXPORT(bool) has_mouse(void); -extern NCURSES_EXPORT(int) getmouse (MEVENT *); -extern NCURSES_EXPORT(int) ungetmouse (MEVENT *); -extern NCURSES_EXPORT(mmask_t) mousemask (mmask_t, mmask_t *); -extern NCURSES_EXPORT(bool) wenclose (const WINDOW *, int, int); -extern NCURSES_EXPORT(int) mouseinterval (int); -extern NCURSES_EXPORT(bool) wmouse_trafo (const WINDOW*, int*, int*, bool); -extern NCURSES_EXPORT(bool) mouse_trafo (int*, int*, bool); /* generated */ - -#if NCURSES_SP_FUNCS -extern NCURSES_EXPORT(bool) NCURSES_SP_NAME(has_mouse) (SCREEN*); -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(getmouse) (SCREEN*, MEVENT *); -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(ungetmouse) (SCREEN*,MEVENT *); -extern NCURSES_EXPORT(mmask_t) NCURSES_SP_NAME(mousemask) (SCREEN*, mmask_t, mmask_t *); -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(mouseinterval) (SCREEN*, int); -#endif - -#define mouse_trafo(y,x,to_screen) wmouse_trafo(stdscr,y,x,to_screen) - -/* other non-XSI functions */ - -extern NCURSES_EXPORT(int) mcprint (char *, int); /* direct data to printer */ -extern NCURSES_EXPORT(int) has_key (int); /* do we have given key? */ - -#if NCURSES_SP_FUNCS -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(has_key) (SCREEN*, int); /* do we have given key? */ -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(mcprint) (SCREEN*, char *, int); /* direct data to printer */ -#endif - -/* Debugging : use with libncurses_g.a */ - -extern NCURSES_EXPORT(void) _tracef (const char *, ...) GCC_PRINTFLIKE(1,2); -extern NCURSES_EXPORT(void) _tracedump (const char *, WINDOW *); -extern NCURSES_EXPORT(char *) _traceattr (attr_t); -extern NCURSES_EXPORT(char *) _traceattr2 (int, chtype); -extern NCURSES_EXPORT(char *) _nc_tracebits (void); -extern NCURSES_EXPORT(char *) _tracechar (int); -extern NCURSES_EXPORT(char *) _tracechtype (chtype); -extern NCURSES_EXPORT(char *) _tracechtype2 (int, chtype); -#ifdef NCURSES_WIDECHAR -#define _tracech_t _tracecchar_t -extern NCURSES_EXPORT(char *) _tracecchar_t (const cchar_t *); -#define _tracech_t2 _tracecchar_t2 -extern NCURSES_EXPORT(char *) _tracecchar_t2 (int, const cchar_t *); -#else -#define _tracech_t _tracechtype -#define _tracech_t2 _tracechtype2 -#endif -extern NCURSES_EXPORT(char *) _tracemouse (const MEVENT *); -extern NCURSES_EXPORT(void) trace (const unsigned int); - -/* trace masks */ -#define TRACE_DISABLE 0x0000 /* turn off tracing */ -#define TRACE_TIMES 0x0001 /* trace user and system times of updates */ -#define TRACE_TPUTS 0x0002 /* trace tputs calls */ -#define TRACE_UPDATE 0x0004 /* trace update actions, old & new screens */ -#define TRACE_MOVE 0x0008 /* trace cursor moves and scrolls */ -#define TRACE_CHARPUT 0x0010 /* trace all character outputs */ -#define TRACE_ORDINARY 0x001F /* trace all update actions */ -#define TRACE_CALLS 0x0020 /* trace all curses calls */ -#define TRACE_VIRTPUT 0x0040 /* trace virtual character puts */ -#define TRACE_IEVENT 0x0080 /* trace low-level input processing */ -#define TRACE_BITS 0x0100 /* trace state of TTY control bits */ -#define TRACE_ICALLS 0x0200 /* trace internal/nested calls */ -#define TRACE_CCALLS 0x0400 /* trace per-character calls */ -#define TRACE_DATABASE 0x0800 /* trace read/write of terminfo/termcap data */ -#define TRACE_ATTRS 0x1000 /* trace attribute updates */ - -#define TRACE_SHIFT 13 /* number of bits in the trace masks */ -#define TRACE_MAXIMUM ((1 << TRACE_SHIFT) - 1) /* maximum trace level */ - -#if defined(TRACE) || defined(NCURSES_TEST) -extern NCURSES_EXPORT_VAR(int) _nc_optimize_enable; /* enable optimizations */ -extern NCURSES_EXPORT(const char *) _nc_visbuf (const char *); -#define OPTIMIZE_MVCUR 0x01 /* cursor movement optimization */ -#define OPTIMIZE_HASHMAP 0x02 /* diff hashing to detect scrolls */ -#define OPTIMIZE_SCROLL 0x04 /* scroll optimization */ -#define OPTIMIZE_ALL 0xff /* enable all optimizations (dflt) */ -#endif - -#include - -#ifdef __cplusplus - -#ifndef NCURSES_NOMACROS - -/* these names conflict with STL */ -#undef box -#undef clear -#undef erase -#undef move -#undef refresh - -#endif /* NCURSES_NOMACROS */ - -} -#endif - -#endif /* __NCURSES_H */ diff --git a/windows/ncurses/include/ncurses/ncurses_dll.h b/windows/ncurses/include/ncurses/ncurses_dll.h deleted file mode 100644 index 6974fcba0..000000000 --- a/windows/ncurses/include/ncurses/ncurses_dll.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2007,2009 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ -/* $Id: ncurses_dll.h.in,v 1.8 2009/04/04 22:26:27 tom Exp $ */ - -#ifndef NCURSES_DLL_H_incl -#define NCURSES_DLL_H_incl 1 - -/* - * For reentrant code, we map the various global variables into SCREEN by - * using functions to access them. - */ -#define NCURSES_PUBLIC_VAR(name) _nc_##name -#define NCURSES_WRAPPED_VAR(type,name) extern type NCURSES_PUBLIC_VAR(name)(void) - -/* no longer needed on cygwin or mingw, thanks to auto-import */ -/* but this structure may be useful at some point for an MSVC build */ -/* so, for now unconditionally define the important flags */ -/* "the right way" for proper static and dll+auto-import behavior */ -#undef NCURSES_DLL -#define NCURSES_STATIC - -#if defined(__CYGWIN__) || defined(__MINGW32__) -# if defined(NCURSES_DLL) -# if defined(NCURSES_STATIC) -# undef NCURSES_STATIC -# endif -# endif -# undef NCURSES_IMPEXP -# undef NCURSES_API -# undef NCURSES_EXPORT -# undef NCURSES_EXPORT_VAR -# if defined(NCURSES_DLL) -/* building a DLL */ -# define NCURSES_IMPEXP __declspec(dllexport) -# elif defined(NCURSES_STATIC) -/* building or linking to a static library */ -# define NCURSES_IMPEXP /* nothing */ -# else -/* linking to the DLL */ -# define NCURSES_IMPEXP __declspec(dllimport) -# endif -# define NCURSES_API __cdecl -# define NCURSES_EXPORT(type) NCURSES_IMPEXP type NCURSES_API -# define NCURSES_EXPORT_VAR(type) NCURSES_IMPEXP type -#endif - -/* Take care of non-cygwin platforms */ -#if !defined(NCURSES_IMPEXP) -# define NCURSES_IMPEXP /* nothing */ -#endif -#if !defined(NCURSES_API) -# define NCURSES_API /* nothing */ -#endif -#if !defined(NCURSES_EXPORT) -# define NCURSES_EXPORT(type) NCURSES_IMPEXP type NCURSES_API -#endif -#if !defined(NCURSES_EXPORT_VAR) -# define NCURSES_EXPORT_VAR(type) __declspec(dllimport) type -#endif - -#endif /* NCURSES_DLL_H_incl */ diff --git a/windows/ncurses/include/ncurses/panel.h b/windows/ncurses/include/ncurses/panel.h deleted file mode 100644 index 4d5aca279..000000000 --- a/windows/ncurses/include/ncurses/panel.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2006,2009 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Zeyd M. Ben-Halim 1995 * - * and: Eric S. Raymond * - * and: Juergen Pfeifer 1996-1999,2008 * - ****************************************************************************/ - -/* $Id: panel.h,v 1.11 2009/04/11 19:50:40 tom Exp $ */ - -/* panel.h -- interface file for panels library */ - -#ifndef NCURSES_PANEL_H_incl -#define NCURSES_PANEL_H_incl 1 - -#include - -typedef struct panel -{ - WINDOW *win; - struct panel *below; - struct panel *above; - NCURSES_CONST void *user; -} PANEL; - -#if defined(__cplusplus) -extern "C" { -#endif - -extern NCURSES_EXPORT(WINDOW*) panel_window (const PANEL *); -extern NCURSES_EXPORT(void) update_panels (void); -extern NCURSES_EXPORT(int) hide_panel (PANEL *); -extern NCURSES_EXPORT(int) show_panel (PANEL *); -extern NCURSES_EXPORT(int) del_panel (PANEL *); -extern NCURSES_EXPORT(int) top_panel (PANEL *); -extern NCURSES_EXPORT(int) bottom_panel (PANEL *); -extern NCURSES_EXPORT(PANEL*) new_panel (WINDOW *); -extern NCURSES_EXPORT(PANEL*) panel_above (const PANEL *); -extern NCURSES_EXPORT(PANEL*) panel_below (const PANEL *); -extern NCURSES_EXPORT(int) set_panel_userptr (PANEL *, NCURSES_CONST void *); -extern NCURSES_EXPORT(NCURSES_CONST void*) panel_userptr (const PANEL *); -extern NCURSES_EXPORT(int) move_panel (PANEL *, int, int); -extern NCURSES_EXPORT(int) replace_panel (PANEL *,WINDOW *); -extern NCURSES_EXPORT(int) panel_hidden (const PANEL *); - -#if NCURSES_SP_FUNCS -extern NCURSES_EXPORT(PANEL *) ground_panel(SCREEN *); -extern NCURSES_EXPORT(PANEL *) ceiling_panel(SCREEN *); - -extern NCURSES_EXPORT(void) NCURSES_SP_NAME(update_panels) (SCREEN*); -#endif - -#if defined(__cplusplus) -} -#endif - -#endif /* NCURSES_PANEL_H_incl */ - -/* end of panel.h */ diff --git a/windows/ncurses/include/ncurses/term.h b/windows/ncurses/include/ncurses/term.h deleted file mode 100644 index 543a18df8..000000000 --- a/windows/ncurses/include/ncurses/term.h +++ /dev/null @@ -1,834 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/****************************************************************************/ -/* Author: Zeyd M. Ben-Halim 1992,1995 */ -/* and: Eric S. Raymond */ -/* and: Thomas E. Dickey 1995-on */ -/****************************************************************************/ - -/* $Id: MKterm.h.awk.in,v 1.58 2010/01/09 19:53:26 tom Exp $ */ - -/* -** term.h -- Definition of struct term -*/ - -#ifndef NCURSES_TERM_H_incl -#define NCURSES_TERM_H_incl 1 - -#undef NCURSES_VERSION -#define NCURSES_VERSION "5.9" - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* Make this file self-contained by providing defaults for the HAVE_TERMIO[S]_H - * definition (based on the system for which this was configured). - */ - -#undef NCURSES_CONST -#define NCURSES_CONST /*nothing*/ - -#undef NCURSES_SBOOL -#define NCURSES_SBOOL char - -#undef NCURSES_XNAMES -#define NCURSES_XNAMES 1 - -/* We will use these symbols to hide differences between - * termios/termio/sgttyb interfaces. - */ -#undef TTY -#undef SET_TTY -#undef GET_TTY - -/* Assume POSIX termio if we have the header and function */ -/* #if HAVE_TERMIOS_H && HAVE_TCGETATTR */ -#if 0 && 0 - -#undef TERMIOS -#define TERMIOS 1 - -#include -#define TTY struct termios - -#else /* !HAVE_TERMIOS_H */ - -/* #if HAVE_TERMIO_H */ -#if 0 - -#undef TERMIOS -#define TERMIOS 1 - -#include -#define TTY struct termio - -/* Add definitions to make termio look like termios. - * But ifdef it, since there are some implementations - * that try to do this for us in a fake . - */ -#ifndef TCSANOW -#define TCSANOW TCSETA -#endif -#ifndef TCSADRAIN -#define TCSADRAIN TCSETAW -#endif -#ifndef TCSAFLUSH -#define TCSAFLUSH TCSETAF -#endif -#ifndef tcsetattr -#define tcsetattr(fd, cmd, arg) ioctl(fd, cmd, arg) -#endif -#ifndef tcgetattr -#define tcgetattr(fd, arg) ioctl(fd, TCGETA, arg) -#endif -#ifndef cfgetospeed -#define cfgetospeed(t) ((t)->c_cflag & CBAUD) -#endif -#ifndef TCIFLUSH -#define TCIFLUSH 0 -#endif -#ifndef TCOFLUSH -#define TCOFLUSH 1 -#endif -#ifndef TCIOFLUSH -#define TCIOFLUSH 2 -#endif -#ifndef tcflush -#define tcflush(fd, arg) ioctl(fd, TCFLSH, arg) -#endif - -#else /* !HAVE_TERMIO_H */ - -#if __MINGW32__ -# include -# define TTY struct termios -#else -#undef TERMIOS -#include -#include -#define TTY struct sgttyb -#endif /* MINGW32 */ -#endif /* HAVE_TERMIO_H */ - -#endif /* HAVE_TERMIOS_H */ - -#ifdef TERMIOS -#define GET_TTY(fd, buf) tcgetattr(fd, buf) -#define SET_TTY(fd, buf) tcsetattr(fd, TCSADRAIN, buf) -#else -#define GET_TTY(fd, buf) gtty(fd, buf) -#define SET_TTY(fd, buf) stty(fd, buf) -#endif - -#define NAMESIZE 256 - -#define CUR cur_term->type. - -#define auto_left_margin CUR Booleans[0] -#define auto_right_margin CUR Booleans[1] -#define no_esc_ctlc CUR Booleans[2] -#define ceol_standout_glitch CUR Booleans[3] -#define eat_newline_glitch CUR Booleans[4] -#define erase_overstrike CUR Booleans[5] -#define generic_type CUR Booleans[6] -#define hard_copy CUR Booleans[7] -#define has_meta_key CUR Booleans[8] -#define has_status_line CUR Booleans[9] -#define insert_null_glitch CUR Booleans[10] -#define memory_above CUR Booleans[11] -#define memory_below CUR Booleans[12] -#define move_insert_mode CUR Booleans[13] -#define move_standout_mode CUR Booleans[14] -#define over_strike CUR Booleans[15] -#define status_line_esc_ok CUR Booleans[16] -#define dest_tabs_magic_smso CUR Booleans[17] -#define tilde_glitch CUR Booleans[18] -#define transparent_underline CUR Booleans[19] -#define xon_xoff CUR Booleans[20] -#define needs_xon_xoff CUR Booleans[21] -#define prtr_silent CUR Booleans[22] -#define hard_cursor CUR Booleans[23] -#define non_rev_rmcup CUR Booleans[24] -#define no_pad_char CUR Booleans[25] -#define non_dest_scroll_region CUR Booleans[26] -#define can_change CUR Booleans[27] -#define back_color_erase CUR Booleans[28] -#define hue_lightness_saturation CUR Booleans[29] -#define col_addr_glitch CUR Booleans[30] -#define cr_cancels_micro_mode CUR Booleans[31] -#define has_print_wheel CUR Booleans[32] -#define row_addr_glitch CUR Booleans[33] -#define semi_auto_right_margin CUR Booleans[34] -#define cpi_changes_res CUR Booleans[35] -#define lpi_changes_res CUR Booleans[36] -#define columns CUR Numbers[0] -#define init_tabs CUR Numbers[1] -#define lines CUR Numbers[2] -#define lines_of_memory CUR Numbers[3] -#define magic_cookie_glitch CUR Numbers[4] -#define padding_baud_rate CUR Numbers[5] -#define virtual_terminal CUR Numbers[6] -#define width_status_line CUR Numbers[7] -#define num_labels CUR Numbers[8] -#define label_height CUR Numbers[9] -#define label_width CUR Numbers[10] -#define max_attributes CUR Numbers[11] -#define maximum_windows CUR Numbers[12] -#define max_colors CUR Numbers[13] -#define max_pairs CUR Numbers[14] -#define no_color_video CUR Numbers[15] -#define buffer_capacity CUR Numbers[16] -#define dot_vert_spacing CUR Numbers[17] -#define dot_horz_spacing CUR Numbers[18] -#define max_micro_address CUR Numbers[19] -#define max_micro_jump CUR Numbers[20] -#define micro_col_size CUR Numbers[21] -#define micro_line_size CUR Numbers[22] -#define number_of_pins CUR Numbers[23] -#define output_res_char CUR Numbers[24] -#define output_res_line CUR Numbers[25] -#define output_res_horz_inch CUR Numbers[26] -#define output_res_vert_inch CUR Numbers[27] -#define print_rate CUR Numbers[28] -#define wide_char_size CUR Numbers[29] -#define buttons CUR Numbers[30] -#define bit_image_entwining CUR Numbers[31] -#define bit_image_type CUR Numbers[32] -#define back_tab CUR Strings[0] -#define bell CUR Strings[1] -#define carriage_return CUR Strings[2] -#define change_scroll_region CUR Strings[3] -#define clear_all_tabs CUR Strings[4] -#define clear_screen CUR Strings[5] -#define clr_eol CUR Strings[6] -#define clr_eos CUR Strings[7] -#define column_address CUR Strings[8] -#define command_character CUR Strings[9] -#define cursor_address CUR Strings[10] -#define cursor_down CUR Strings[11] -#define cursor_home CUR Strings[12] -#define cursor_invisible CUR Strings[13] -#define cursor_left CUR Strings[14] -#define cursor_mem_address CUR Strings[15] -#define cursor_normal CUR Strings[16] -#define cursor_right CUR Strings[17] -#define cursor_to_ll CUR Strings[18] -#define cursor_up CUR Strings[19] -#define cursor_visible CUR Strings[20] -#define delete_character CUR Strings[21] -#define delete_line CUR Strings[22] -#define dis_status_line CUR Strings[23] -#define down_half_line CUR Strings[24] -#define enter_alt_charset_mode CUR Strings[25] -#define enter_blink_mode CUR Strings[26] -#define enter_bold_mode CUR Strings[27] -#define enter_ca_mode CUR Strings[28] -#define enter_delete_mode CUR Strings[29] -#define enter_dim_mode CUR Strings[30] -#define enter_insert_mode CUR Strings[31] -#define enter_secure_mode CUR Strings[32] -#define enter_protected_mode CUR Strings[33] -#define enter_reverse_mode CUR Strings[34] -#define enter_standout_mode CUR Strings[35] -#define enter_underline_mode CUR Strings[36] -#define erase_chars CUR Strings[37] -#define exit_alt_charset_mode CUR Strings[38] -#define exit_attribute_mode CUR Strings[39] -#define exit_ca_mode CUR Strings[40] -#define exit_delete_mode CUR Strings[41] -#define exit_insert_mode CUR Strings[42] -#define exit_standout_mode CUR Strings[43] -#define exit_underline_mode CUR Strings[44] -#define flash_screen CUR Strings[45] -#define form_feed CUR Strings[46] -#define from_status_line CUR Strings[47] -#define init_1string CUR Strings[48] -#define init_2string CUR Strings[49] -#define init_3string CUR Strings[50] -#define init_file CUR Strings[51] -#define insert_character CUR Strings[52] -#define insert_line CUR Strings[53] -#define insert_padding CUR Strings[54] -#define key_backspace CUR Strings[55] -#define key_catab CUR Strings[56] -#define key_clear CUR Strings[57] -#define key_ctab CUR Strings[58] -#define key_dc CUR Strings[59] -#define key_dl CUR Strings[60] -#define key_down CUR Strings[61] -#define key_eic CUR Strings[62] -#define key_eol CUR Strings[63] -#define key_eos CUR Strings[64] -#define key_f0 CUR Strings[65] -#define key_f1 CUR Strings[66] -#define key_f10 CUR Strings[67] -#define key_f2 CUR Strings[68] -#define key_f3 CUR Strings[69] -#define key_f4 CUR Strings[70] -#define key_f5 CUR Strings[71] -#define key_f6 CUR Strings[72] -#define key_f7 CUR Strings[73] -#define key_f8 CUR Strings[74] -#define key_f9 CUR Strings[75] -#define key_home CUR Strings[76] -#define key_ic CUR Strings[77] -#define key_il CUR Strings[78] -#define key_left CUR Strings[79] -#define key_ll CUR Strings[80] -#define key_npage CUR Strings[81] -#define key_ppage CUR Strings[82] -#define key_right CUR Strings[83] -#define key_sf CUR Strings[84] -#define key_sr CUR Strings[85] -#define key_stab CUR Strings[86] -#define key_up CUR Strings[87] -#define keypad_local CUR Strings[88] -#define keypad_xmit CUR Strings[89] -#define lab_f0 CUR Strings[90] -#define lab_f1 CUR Strings[91] -#define lab_f10 CUR Strings[92] -#define lab_f2 CUR Strings[93] -#define lab_f3 CUR Strings[94] -#define lab_f4 CUR Strings[95] -#define lab_f5 CUR Strings[96] -#define lab_f6 CUR Strings[97] -#define lab_f7 CUR Strings[98] -#define lab_f8 CUR Strings[99] -#define lab_f9 CUR Strings[100] -#define meta_off CUR Strings[101] -#define meta_on CUR Strings[102] -#define newline CUR Strings[103] -#define pad_char CUR Strings[104] -#define parm_dch CUR Strings[105] -#define parm_delete_line CUR Strings[106] -#define parm_down_cursor CUR Strings[107] -#define parm_ich CUR Strings[108] -#define parm_index CUR Strings[109] -#define parm_insert_line CUR Strings[110] -#define parm_left_cursor CUR Strings[111] -#define parm_right_cursor CUR Strings[112] -#define parm_rindex CUR Strings[113] -#define parm_up_cursor CUR Strings[114] -#define pkey_key CUR Strings[115] -#define pkey_local CUR Strings[116] -#define pkey_xmit CUR Strings[117] -#define print_screen CUR Strings[118] -#define prtr_off CUR Strings[119] -#define prtr_on CUR Strings[120] -#define repeat_char CUR Strings[121] -#define reset_1string CUR Strings[122] -#define reset_2string CUR Strings[123] -#define reset_3string CUR Strings[124] -#define reset_file CUR Strings[125] -#define restore_cursor CUR Strings[126] -#define row_address CUR Strings[127] -#define save_cursor CUR Strings[128] -#define scroll_forward CUR Strings[129] -#define scroll_reverse CUR Strings[130] -#define set_attributes CUR Strings[131] -#define set_tab CUR Strings[132] -#define set_window CUR Strings[133] -#define tab CUR Strings[134] -#define to_status_line CUR Strings[135] -#define underline_char CUR Strings[136] -#define up_half_line CUR Strings[137] -#define init_prog CUR Strings[138] -#define key_a1 CUR Strings[139] -#define key_a3 CUR Strings[140] -#define key_b2 CUR Strings[141] -#define key_c1 CUR Strings[142] -#define key_c3 CUR Strings[143] -#define prtr_non CUR Strings[144] -#define char_padding CUR Strings[145] -#define acs_chars CUR Strings[146] -#define plab_norm CUR Strings[147] -#define key_btab CUR Strings[148] -#define enter_xon_mode CUR Strings[149] -#define exit_xon_mode CUR Strings[150] -#define enter_am_mode CUR Strings[151] -#define exit_am_mode CUR Strings[152] -#define xon_character CUR Strings[153] -#define xoff_character CUR Strings[154] -#define ena_acs CUR Strings[155] -#define label_on CUR Strings[156] -#define label_off CUR Strings[157] -#define key_beg CUR Strings[158] -#define key_cancel CUR Strings[159] -#define key_close CUR Strings[160] -#define key_command CUR Strings[161] -#define key_copy CUR Strings[162] -#define key_create CUR Strings[163] -#define key_end CUR Strings[164] -#define key_enter CUR Strings[165] -#define key_exit CUR Strings[166] -#define key_find CUR Strings[167] -#define key_help CUR Strings[168] -#define key_mark CUR Strings[169] -#define key_message CUR Strings[170] -#define key_move CUR Strings[171] -#define key_next CUR Strings[172] -#define key_open CUR Strings[173] -#define key_options CUR Strings[174] -#define key_previous CUR Strings[175] -#define key_print CUR Strings[176] -#define key_redo CUR Strings[177] -#define key_reference CUR Strings[178] -#define key_refresh CUR Strings[179] -#define key_replace CUR Strings[180] -#define key_restart CUR Strings[181] -#define key_resume CUR Strings[182] -#define key_save CUR Strings[183] -#define key_suspend CUR Strings[184] -#define key_undo CUR Strings[185] -#define key_sbeg CUR Strings[186] -#define key_scancel CUR Strings[187] -#define key_scommand CUR Strings[188] -#define key_scopy CUR Strings[189] -#define key_screate CUR Strings[190] -#define key_sdc CUR Strings[191] -#define key_sdl CUR Strings[192] -#define key_select CUR Strings[193] -#define key_send CUR Strings[194] -#define key_seol CUR Strings[195] -#define key_sexit CUR Strings[196] -#define key_sfind CUR Strings[197] -#define key_shelp CUR Strings[198] -#define key_shome CUR Strings[199] -#define key_sic CUR Strings[200] -#define key_sleft CUR Strings[201] -#define key_smessage CUR Strings[202] -#define key_smove CUR Strings[203] -#define key_snext CUR Strings[204] -#define key_soptions CUR Strings[205] -#define key_sprevious CUR Strings[206] -#define key_sprint CUR Strings[207] -#define key_sredo CUR Strings[208] -#define key_sreplace CUR Strings[209] -#define key_sright CUR Strings[210] -#define key_srsume CUR Strings[211] -#define key_ssave CUR Strings[212] -#define key_ssuspend CUR Strings[213] -#define key_sundo CUR Strings[214] -#define req_for_input CUR Strings[215] -#define key_f11 CUR Strings[216] -#define key_f12 CUR Strings[217] -#define key_f13 CUR Strings[218] -#define key_f14 CUR Strings[219] -#define key_f15 CUR Strings[220] -#define key_f16 CUR Strings[221] -#define key_f17 CUR Strings[222] -#define key_f18 CUR Strings[223] -#define key_f19 CUR Strings[224] -#define key_f20 CUR Strings[225] -#define key_f21 CUR Strings[226] -#define key_f22 CUR Strings[227] -#define key_f23 CUR Strings[228] -#define key_f24 CUR Strings[229] -#define key_f25 CUR Strings[230] -#define key_f26 CUR Strings[231] -#define key_f27 CUR Strings[232] -#define key_f28 CUR Strings[233] -#define key_f29 CUR Strings[234] -#define key_f30 CUR Strings[235] -#define key_f31 CUR Strings[236] -#define key_f32 CUR Strings[237] -#define key_f33 CUR Strings[238] -#define key_f34 CUR Strings[239] -#define key_f35 CUR Strings[240] -#define key_f36 CUR Strings[241] -#define key_f37 CUR Strings[242] -#define key_f38 CUR Strings[243] -#define key_f39 CUR Strings[244] -#define key_f40 CUR Strings[245] -#define key_f41 CUR Strings[246] -#define key_f42 CUR Strings[247] -#define key_f43 CUR Strings[248] -#define key_f44 CUR Strings[249] -#define key_f45 CUR Strings[250] -#define key_f46 CUR Strings[251] -#define key_f47 CUR Strings[252] -#define key_f48 CUR Strings[253] -#define key_f49 CUR Strings[254] -#define key_f50 CUR Strings[255] -#define key_f51 CUR Strings[256] -#define key_f52 CUR Strings[257] -#define key_f53 CUR Strings[258] -#define key_f54 CUR Strings[259] -#define key_f55 CUR Strings[260] -#define key_f56 CUR Strings[261] -#define key_f57 CUR Strings[262] -#define key_f58 CUR Strings[263] -#define key_f59 CUR Strings[264] -#define key_f60 CUR Strings[265] -#define key_f61 CUR Strings[266] -#define key_f62 CUR Strings[267] -#define key_f63 CUR Strings[268] -#define clr_bol CUR Strings[269] -#define clear_margins CUR Strings[270] -#define set_left_margin CUR Strings[271] -#define set_right_margin CUR Strings[272] -#define label_format CUR Strings[273] -#define set_clock CUR Strings[274] -#define display_clock CUR Strings[275] -#define remove_clock CUR Strings[276] -#define create_window CUR Strings[277] -#define goto_window CUR Strings[278] -#define hangup CUR Strings[279] -#define dial_phone CUR Strings[280] -#define quick_dial CUR Strings[281] -#define tone CUR Strings[282] -#define pulse CUR Strings[283] -#define flash_hook CUR Strings[284] -#define fixed_pause CUR Strings[285] -#define wait_tone CUR Strings[286] -#define user0 CUR Strings[287] -#define user1 CUR Strings[288] -#define user2 CUR Strings[289] -#define user3 CUR Strings[290] -#define user4 CUR Strings[291] -#define user5 CUR Strings[292] -#define user6 CUR Strings[293] -#define user7 CUR Strings[294] -#define user8 CUR Strings[295] -#define user9 CUR Strings[296] -#define orig_pair CUR Strings[297] -#define orig_colors CUR Strings[298] -#define initialize_color CUR Strings[299] -#define initialize_pair CUR Strings[300] -#define set_color_pair CUR Strings[301] -#define set_foreground CUR Strings[302] -#define set_background CUR Strings[303] -#define change_char_pitch CUR Strings[304] -#define change_line_pitch CUR Strings[305] -#define change_res_horz CUR Strings[306] -#define change_res_vert CUR Strings[307] -#define define_char CUR Strings[308] -#define enter_doublewide_mode CUR Strings[309] -#define enter_draft_quality CUR Strings[310] -#define enter_italics_mode CUR Strings[311] -#define enter_leftward_mode CUR Strings[312] -#define enter_micro_mode CUR Strings[313] -#define enter_near_letter_quality CUR Strings[314] -#define enter_normal_quality CUR Strings[315] -#define enter_shadow_mode CUR Strings[316] -#define enter_subscript_mode CUR Strings[317] -#define enter_superscript_mode CUR Strings[318] -#define enter_upward_mode CUR Strings[319] -#define exit_doublewide_mode CUR Strings[320] -#define exit_italics_mode CUR Strings[321] -#define exit_leftward_mode CUR Strings[322] -#define exit_micro_mode CUR Strings[323] -#define exit_shadow_mode CUR Strings[324] -#define exit_subscript_mode CUR Strings[325] -#define exit_superscript_mode CUR Strings[326] -#define exit_upward_mode CUR Strings[327] -#define micro_column_address CUR Strings[328] -#define micro_down CUR Strings[329] -#define micro_left CUR Strings[330] -#define micro_right CUR Strings[331] -#define micro_row_address CUR Strings[332] -#define micro_up CUR Strings[333] -#define order_of_pins CUR Strings[334] -#define parm_down_micro CUR Strings[335] -#define parm_left_micro CUR Strings[336] -#define parm_right_micro CUR Strings[337] -#define parm_up_micro CUR Strings[338] -#define select_char_set CUR Strings[339] -#define set_bottom_margin CUR Strings[340] -#define set_bottom_margin_parm CUR Strings[341] -#define set_left_margin_parm CUR Strings[342] -#define set_right_margin_parm CUR Strings[343] -#define set_top_margin CUR Strings[344] -#define set_top_margin_parm CUR Strings[345] -#define start_bit_image CUR Strings[346] -#define start_char_set_def CUR Strings[347] -#define stop_bit_image CUR Strings[348] -#define stop_char_set_def CUR Strings[349] -#define subscript_characters CUR Strings[350] -#define superscript_characters CUR Strings[351] -#define these_cause_cr CUR Strings[352] -#define zero_motion CUR Strings[353] -#define char_set_names CUR Strings[354] -#define key_mouse CUR Strings[355] -#define mouse_info CUR Strings[356] -#define req_mouse_pos CUR Strings[357] -#define get_mouse CUR Strings[358] -#define set_a_foreground CUR Strings[359] -#define set_a_background CUR Strings[360] -#define pkey_plab CUR Strings[361] -#define device_type CUR Strings[362] -#define code_set_init CUR Strings[363] -#define set0_des_seq CUR Strings[364] -#define set1_des_seq CUR Strings[365] -#define set2_des_seq CUR Strings[366] -#define set3_des_seq CUR Strings[367] -#define set_lr_margin CUR Strings[368] -#define set_tb_margin CUR Strings[369] -#define bit_image_repeat CUR Strings[370] -#define bit_image_newline CUR Strings[371] -#define bit_image_carriage_return CUR Strings[372] -#define color_names CUR Strings[373] -#define define_bit_image_region CUR Strings[374] -#define end_bit_image_region CUR Strings[375] -#define set_color_band CUR Strings[376] -#define set_page_length CUR Strings[377] -#define display_pc_char CUR Strings[378] -#define enter_pc_charset_mode CUR Strings[379] -#define exit_pc_charset_mode CUR Strings[380] -#define enter_scancode_mode CUR Strings[381] -#define exit_scancode_mode CUR Strings[382] -#define pc_term_options CUR Strings[383] -#define scancode_escape CUR Strings[384] -#define alt_scancode_esc CUR Strings[385] -#define enter_horizontal_hl_mode CUR Strings[386] -#define enter_left_hl_mode CUR Strings[387] -#define enter_low_hl_mode CUR Strings[388] -#define enter_right_hl_mode CUR Strings[389] -#define enter_top_hl_mode CUR Strings[390] -#define enter_vertical_hl_mode CUR Strings[391] -#define set_a_attributes CUR Strings[392] -#define set_pglen_inch CUR Strings[393] - -#define BOOLWRITE 37 -#define NUMWRITE 33 -#define STRWRITE 394 - -/* older synonyms for some capabilities */ -#define beehive_glitch no_esc_ctlc -#define teleray_glitch dest_tabs_magic_smso -#define micro_char_size micro_col_size - -#ifdef __INTERNAL_CAPS_VISIBLE -#define termcap_init2 CUR Strings[394] -#define termcap_reset CUR Strings[395] -#define magic_cookie_glitch_ul CUR Numbers[33] -#define backspaces_with_bs CUR Booleans[37] -#define crt_no_scrolling CUR Booleans[38] -#define no_correctly_working_cr CUR Booleans[39] -#define carriage_return_delay CUR Numbers[34] -#define new_line_delay CUR Numbers[35] -#define linefeed_if_not_lf CUR Strings[396] -#define backspace_if_not_bs CUR Strings[397] -#define gnu_has_meta_key CUR Booleans[40] -#define linefeed_is_newline CUR Booleans[41] -#define backspace_delay CUR Numbers[36] -#define horizontal_tab_delay CUR Numbers[37] -#define number_of_function_keys CUR Numbers[38] -#define other_non_function_keys CUR Strings[398] -#define arrow_key_map CUR Strings[399] -#define has_hardware_tabs CUR Booleans[42] -#define return_does_clr_eol CUR Booleans[43] -#define acs_ulcorner CUR Strings[400] -#define acs_llcorner CUR Strings[401] -#define acs_urcorner CUR Strings[402] -#define acs_lrcorner CUR Strings[403] -#define acs_ltee CUR Strings[404] -#define acs_rtee CUR Strings[405] -#define acs_btee CUR Strings[406] -#define acs_ttee CUR Strings[407] -#define acs_hline CUR Strings[408] -#define acs_vline CUR Strings[409] -#define acs_plus CUR Strings[410] -#define memory_lock CUR Strings[411] -#define memory_unlock CUR Strings[412] -#define box_chars_1 CUR Strings[413] -#endif /* __INTERNAL_CAPS_VISIBLE */ - - -/* - * Predefined terminfo array sizes - */ -#define BOOLCOUNT 44 -#define NUMCOUNT 39 -#define STRCOUNT 414 - -/* used by code for comparing entries */ -#define acs_chars_index 146 - -typedef struct termtype { /* in-core form of terminfo data */ - char *term_names; /* str_table offset of term names */ - char *str_table; /* pointer to string table */ - NCURSES_SBOOL *Booleans; /* array of boolean values */ - short *Numbers; /* array of integer values */ - char **Strings; /* array of string offsets */ - -#if NCURSES_XNAMES - char *ext_str_table; /* pointer to extended string table */ - char **ext_Names; /* corresponding names */ - - unsigned short num_Booleans;/* count total Booleans */ - unsigned short num_Numbers; /* count total Numbers */ - unsigned short num_Strings; /* count total Strings */ - - unsigned short ext_Booleans;/* count extensions to Booleans */ - unsigned short ext_Numbers; /* count extensions to Numbers */ - unsigned short ext_Strings; /* count extensions to Strings */ -#endif /* NCURSES_XNAMES */ - -} TERMTYPE; - -typedef struct term { /* describe an actual terminal */ - TERMTYPE type; /* terminal type description */ - short Filedes; /* file description being written to */ - TTY Ottyb, /* original state of the terminal */ - Nttyb; /* current state of the terminal */ - int _baudrate; /* used to compute padding */ - char * _termname; /* used for termname() */ -} TERMINAL; - -#if 0 && !0 -extern NCURSES_EXPORT_VAR(TERMINAL *) cur_term; -#elif 0 -NCURSES_WRAPPED_VAR(TERMINAL *, cur_term); -#define cur_term NCURSES_PUBLIC_VAR(cur_term()) -#else -extern NCURSES_EXPORT_VAR(TERMINAL *) cur_term; -#endif - -#if 0 || 0 -NCURSES_WRAPPED_VAR(NCURSES_CONST char * const *, boolnames); -NCURSES_WRAPPED_VAR(NCURSES_CONST char * const *, boolcodes); -NCURSES_WRAPPED_VAR(NCURSES_CONST char * const *, boolfnames); -NCURSES_WRAPPED_VAR(NCURSES_CONST char * const *, numnames); -NCURSES_WRAPPED_VAR(NCURSES_CONST char * const *, numcodes); -NCURSES_WRAPPED_VAR(NCURSES_CONST char * const *, numfnames); -NCURSES_WRAPPED_VAR(NCURSES_CONST char * const *, strnames); -NCURSES_WRAPPED_VAR(NCURSES_CONST char * const *, strcodes); -NCURSES_WRAPPED_VAR(NCURSES_CONST char * const *, strfnames); - -#define boolnames NCURSES_PUBLIC_VAR(boolnames()) -#define boolcodes NCURSES_PUBLIC_VAR(boolcodes()) -#define boolfnames NCURSES_PUBLIC_VAR(boolfnames()) -#define numnames NCURSES_PUBLIC_VAR(numnames()) -#define numcodes NCURSES_PUBLIC_VAR(numcodes()) -#define numfnames NCURSES_PUBLIC_VAR(numfnames()) -#define strnames NCURSES_PUBLIC_VAR(strnames()) -#define strcodes NCURSES_PUBLIC_VAR(strcodes()) -#define strfnames NCURSES_PUBLIC_VAR(strfnames()) - -#else - -extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) boolnames[]; -extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) boolcodes[]; -extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) boolfnames[]; -extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) numnames[]; -extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) numcodes[]; -extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) numfnames[]; -extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) strnames[]; -extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) strcodes[]; -extern NCURSES_EXPORT_VAR(NCURSES_CONST char * const ) strfnames[]; - -#endif - -/* internals */ -extern NCURSES_EXPORT(int) _nc_set_tty_mode (TTY *buf); -extern NCURSES_EXPORT(int) _nc_get_tty_mode (TTY *buf); -extern NCURSES_EXPORT(int) _nc_read_entry (const char * const, char * const, TERMTYPE *const); -extern NCURSES_EXPORT(int) _nc_read_file_entry (const char *const, TERMTYPE *); -extern NCURSES_EXPORT(int) _nc_read_termtype (TERMTYPE *, char *, int); -extern NCURSES_EXPORT(char *) _nc_first_name (const char *const); -extern NCURSES_EXPORT(int) _nc_name_match (const char *const, const char *const, const char *const); -extern NCURSES_EXPORT(const TERMTYPE *) _nc_fallback (const char *); - -/* entry points */ -extern NCURSES_EXPORT(TERMINAL *) set_curterm (TERMINAL *); -extern NCURSES_EXPORT(int) del_curterm (TERMINAL *); - -/* miscellaneous entry points */ -extern NCURSES_EXPORT(int) restartterm (NCURSES_CONST char *, int, int *); -extern NCURSES_EXPORT(int) setupterm (NCURSES_CONST char *,int,int *); - -/* terminfo entry points, also declared in curses.h */ -#if !defined(__NCURSES_H) -extern NCURSES_EXPORT(char *) tigetstr (NCURSES_CONST char *); -extern NCURSES_EXPORT_VAR(char) ttytype[]; -extern NCURSES_EXPORT(int) putp (const char *); -extern NCURSES_EXPORT(int) tigetflag (NCURSES_CONST char *); -extern NCURSES_EXPORT(int) tigetnum (NCURSES_CONST char *); - -#if 1 /* NCURSES_TPARM_VARARGS */ -extern NCURSES_EXPORT(char *) tparm (NCURSES_CONST char *, ...); /* special */ -#else -extern NCURSES_EXPORT(char *) tparm (NCURSES_CONST char *, long,long,long,long,long,long,long,long,long); /* special */ -extern NCURSES_EXPORT(char *) tparm_varargs (NCURSES_CONST char *, ...); /* special */ -#endif - -extern NCURSES_EXPORT(char *) tiparm (const char *, ...); /* special */ - -#endif /* __NCURSES_H */ - -/* termcap database emulation (XPG4 uses const only for 2nd param of tgetent) */ -#if !defined(NCURSES_TERMCAP_H_incl) -extern NCURSES_EXPORT(char *) tgetstr (NCURSES_CONST char *, char **); -extern NCURSES_EXPORT(char *) tgoto (const char *, int, int); -extern NCURSES_EXPORT(int) tgetent (char *, const char *); -extern NCURSES_EXPORT(int) tgetflag (NCURSES_CONST char *); -extern NCURSES_EXPORT(int) tgetnum (NCURSES_CONST char *); -extern NCURSES_EXPORT(int) tputs (const char *, int, int (*)(int)); -#endif /* NCURSES_TERMCAP_H_incl */ - -/* - * Include curses.h before term.h to enable these extensions. - */ -#if defined(NCURSES_SP_FUNCS) && (NCURSES_SP_FUNCS != 0) - -extern NCURSES_EXPORT(char *) NCURSES_SP_NAME(tigetstr) (SCREEN*, NCURSES_CONST char *); -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(putp) (SCREEN*, const char *); -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(tigetflag) (SCREEN*, NCURSES_CONST char *); -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(tigetnum) (SCREEN*, NCURSES_CONST char *); - -#if 1 /* NCURSES_TPARM_VARARGS */ -extern NCURSES_EXPORT(char *) NCURSES_SP_NAME(tparm) (SCREEN*, NCURSES_CONST char *, ...); /* special */ -#else -extern NCURSES_EXPORT(char *) NCURSES_SP_NAME(tparm) (SCREEN*, NCURSES_CONST char *, long,long,long,long,long,long,long,long,long); /* special */ -extern NCURSES_EXPORT(char *) NCURSES_SP_NAME(tparm_varargs) (SCREEN*, NCURSES_CONST char *, ...); /* special */ -#endif - -/* termcap database emulation (XPG4 uses const only for 2nd param of tgetent) */ -extern NCURSES_EXPORT(char *) NCURSES_SP_NAME(tgetstr) (SCREEN*, NCURSES_CONST char *, char **); -extern NCURSES_EXPORT(char *) NCURSES_SP_NAME(tgoto) (SCREEN*, const char *, int, int); -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(tgetent) (SCREEN*, char *, const char *); -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(tgetflag) (SCREEN*, NCURSES_CONST char *); -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(tgetnum) (SCREEN*, NCURSES_CONST char *); -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(tputs) (SCREEN*, const char *, int, NCURSES_SP_OUTC); - -extern NCURSES_EXPORT(TERMINAL *) NCURSES_SP_NAME(set_curterm) (SCREEN*, TERMINAL *); -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(del_curterm) (SCREEN*, TERMINAL *); - -extern NCURSES_EXPORT(int) NCURSES_SP_NAME(restartterm) (SCREEN*, NCURSES_CONST char *, int, int *); -#endif /* NCURSES_SP_FUNCS */ - -#ifdef __cplusplus -} -#endif - -#endif /* NCURSES_TERM_H_incl */ diff --git a/windows/ncurses/include/ncurses/term_entry.h b/windows/ncurses/include/ncurses/term_entry.h deleted file mode 100644 index 1610438e3..000000000 --- a/windows/ncurses/include/ncurses/term_entry.h +++ /dev/null @@ -1,174 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2008,2009 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Zeyd M. Ben-Halim 1992,1995 * - * and: Eric S. Raymond * - * and: Thomas E. Dickey 1998-on * - ****************************************************************************/ - -/* $Id: term_entry.h,v 1.37 2009/07/11 16:52:29 tom Exp $ */ - -/* - * term_entry.h -- interface to entry-manipulation code - */ - -#ifndef NCURSES_TERM_ENTRY_H_incl -#define NCURSES_TERM_ENTRY_H_incl 1 - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#define MAX_USES 32 -#define MAX_CROSSLINKS 16 - -typedef struct entry { - TERMTYPE tterm; - unsigned nuses; - struct - { - char *name; - struct entry *link; - long line; - } - uses[MAX_USES]; - int ncrosslinks; - struct entry *crosslinks[MAX_CROSSLINKS]; - long cstart, cend; - long startline; - struct entry *next; - struct entry *last; -} -ENTRY; - -#if NCURSES_XNAMES -#define NUM_BOOLEANS(tp) (tp)->num_Booleans -#define NUM_NUMBERS(tp) (tp)->num_Numbers -#define NUM_STRINGS(tp) (tp)->num_Strings -#define EXT_NAMES(tp,i,limit,index,table) (i >= limit) ? tp->ext_Names[index] : table[i] -#else -#define NUM_BOOLEANS(tp) BOOLCOUNT -#define NUM_NUMBERS(tp) NUMCOUNT -#define NUM_STRINGS(tp) STRCOUNT -#define EXT_NAMES(tp,i,limit,index,table) table[i] -#endif - -#define NUM_EXT_NAMES(tp) (unsigned) ((tp)->ext_Booleans + (tp)->ext_Numbers + (tp)->ext_Strings) - -#define for_each_boolean(n,tp) for(n = 0; n < NUM_BOOLEANS(tp); n++) -#define for_each_number(n,tp) for(n = 0; n < NUM_NUMBERS(tp); n++) -#define for_each_string(n,tp) for(n = 0; n < NUM_STRINGS(tp); n++) - -#if NCURSES_XNAMES -#define for_each_ext_boolean(n,tp) for(n = BOOLCOUNT; n < NUM_BOOLEANS(tp); n++) -#define for_each_ext_number(n,tp) for(n = NUMCOUNT; n < NUM_NUMBERS(tp); n++) -#define for_each_ext_string(n,tp) for(n = STRCOUNT; n < NUM_STRINGS(tp); n++) -#endif - -#define ExtBoolname(tp,i,names) EXT_NAMES(tp, i, BOOLCOUNT, (i - (tp->num_Booleans - tp->ext_Booleans)), names) -#define ExtNumname(tp,i,names) EXT_NAMES(tp, i, NUMCOUNT, (i - (tp->num_Numbers - tp->ext_Numbers)) + tp->ext_Booleans, names) -#define ExtStrname(tp,i,names) EXT_NAMES(tp, i, STRCOUNT, (i - (tp->num_Strings - tp->ext_Strings)) + (tp->ext_Numbers + tp->ext_Booleans), names) - -extern NCURSES_EXPORT_VAR(ENTRY *) _nc_head; -extern NCURSES_EXPORT_VAR(ENTRY *) _nc_tail; -#define for_entry_list(qp) for (qp = _nc_head; qp; qp = qp->next) - -#define MAX_LINE 132 - -#define NULLHOOK (bool(*)(ENTRY *))0 - -/* - * Note that WANTED and PRESENT are not simple inverses! If a capability - * has been explicitly cancelled, it's not considered WANTED. - */ -#define WANTED(s) ((s) == ABSENT_STRING) -#define PRESENT(s) (((s) != ABSENT_STRING) && ((s) != CANCELLED_STRING)) - -#define ANDMISSING(p,q) \ - {if (PRESENT(p) && !PRESENT(q)) _nc_warning(#p " but no " #q);} - -#define PAIRED(p,q) \ - { \ - if (PRESENT(q) && !PRESENT(p)) \ - _nc_warning(#q " but no " #p); \ - if (PRESENT(p) && !PRESENT(q)) \ - _nc_warning(#p " but no " #q); \ - } - -/* alloc_entry.c: elementary allocation code */ -extern NCURSES_EXPORT(ENTRY *) _nc_copy_entry (ENTRY *oldp); -extern NCURSES_EXPORT(char *) _nc_save_str (const char *const); -extern NCURSES_EXPORT(void) _nc_init_entry (TERMTYPE *const); -extern NCURSES_EXPORT(void) _nc_merge_entry (TERMTYPE *const, TERMTYPE *const); -extern NCURSES_EXPORT(void) _nc_wrap_entry (ENTRY *const, bool); - -/* alloc_ttype.c: elementary allocation code */ -extern NCURSES_EXPORT(void) _nc_align_termtype (TERMTYPE *, TERMTYPE *); -extern NCURSES_EXPORT(void) _nc_copy_termtype (TERMTYPE *, TERMTYPE *); - -/* free_ttype.c: elementary allocation code */ -extern NCURSES_EXPORT(void) _nc_free_termtype (TERMTYPE *); - -/* lib_acs.c */ -extern NCURSES_EXPORT(void) _nc_init_acs (void); /* corresponds to traditional 'init_acs()' */ - -/* lib_termcap.c: trim sgr0 string for termcap users */ -extern NCURSES_EXPORT(char *) _nc_trim_sgr0 (TERMTYPE *); - -/* parse_entry.c: entry-parsing code */ -#if NCURSES_XNAMES -extern NCURSES_EXPORT_VAR(bool) _nc_user_definable; -extern NCURSES_EXPORT_VAR(bool) _nc_disable_period; -#endif -extern NCURSES_EXPORT(int) _nc_parse_entry (ENTRY *, int, bool); -extern NCURSES_EXPORT(int) _nc_capcmp (const char *, const char *); - -/* write_entry.c: writing an entry to the file system */ -extern NCURSES_EXPORT(void) _nc_set_writedir (char *); -extern NCURSES_EXPORT(void) _nc_write_entry (TERMTYPE *const); - -/* comp_parse.c: entry list handling */ -extern NCURSES_EXPORT(void) _nc_read_entry_source (FILE*, char*, int, bool, bool (*)(ENTRY*)); -extern NCURSES_EXPORT(bool) _nc_entry_match (char *, char *); -extern NCURSES_EXPORT(int) _nc_resolve_uses (bool); /* obs 20040705 */ -extern NCURSES_EXPORT(int) _nc_resolve_uses2 (bool, bool); -extern NCURSES_EXPORT(void) _nc_free_entries (ENTRY *); -extern NCURSES_IMPEXP void NCURSES_API (*_nc_check_termtype)(TERMTYPE *); /* obs 20040705 */ -extern NCURSES_IMPEXP void NCURSES_API (*_nc_check_termtype2)(TERMTYPE *, bool); - -/* trace_xnames.c */ -extern NCURSES_EXPORT(void) _nc_trace_xnames (TERMTYPE *); - -#ifdef __cplusplus -} -#endif - -#endif /* NCURSES_TERM_ENTRY_H_incl */ diff --git a/windows/ncurses/include/ncurses/termcap.h b/windows/ncurses/include/ncurses/termcap.h deleted file mode 100644 index a1d81a154..000000000 --- a/windows/ncurses/include/ncurses/termcap.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998,2000 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Zeyd M. Ben-Halim 1992,1995 * - * and: Eric S. Raymond * - ****************************************************************************/ - -/* $Id: termcap.h.in,v 1.16 2001/03/24 21:53:27 tom Exp $ */ - -#ifndef NCURSES_TERMCAP_H_incl -#define NCURSES_TERMCAP_H_incl 1 - -#undef NCURSES_VERSION -#define NCURSES_VERSION "5.9" - -#include - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -#include - -#undef NCURSES_CONST -#define NCURSES_CONST /*nothing*/ - -#undef NCURSES_OSPEED -#define NCURSES_OSPEED short - -extern NCURSES_EXPORT_VAR(char) PC; -extern NCURSES_EXPORT_VAR(char *) UP; -extern NCURSES_EXPORT_VAR(char *) BC; -extern NCURSES_EXPORT_VAR(NCURSES_OSPEED) ospeed; - -#if !defined(NCURSES_TERM_H_incl) -extern NCURSES_EXPORT(char *) tgetstr (NCURSES_CONST char *, char **); -extern NCURSES_EXPORT(char *) tgoto (const char *, int, int); -extern NCURSES_EXPORT(int) tgetent (char *, const char *); -extern NCURSES_EXPORT(int) tgetflag (NCURSES_CONST char *); -extern NCURSES_EXPORT(int) tgetnum (NCURSES_CONST char *); -extern NCURSES_EXPORT(int) tputs (const char *, int, int (*)(int)); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* NCURSES_TERMCAP_H_incl */ diff --git a/windows/ncurses/include/ncurses/tic.h b/windows/ncurses/include/ncurses/tic.h deleted file mode 100644 index 28ee3882e..000000000 --- a/windows/ncurses/include/ncurses/tic.h +++ /dev/null @@ -1,346 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2007,2009 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Zeyd M. Ben-Halim 1992,1995 * - * and: Eric S. Raymond * - * and: Thomas E. Dickey 1996 on * - ****************************************************************************/ - -/* - * $Id: tic.h,v 1.65 2009/08/08 17:52:46 tom Exp $ - * tic.h - Global variables and structures for the terminfo - * compiler. - */ - -#ifndef __TIC_H -#define __TIC_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include /* for the _tracef() prototype, ERR/OK, bool defs */ - -/* -** The format of compiled terminfo files is as follows: -** -** Header (12 bytes), containing information given below -** Names Section, containing the names of the terminal -** Boolean Section, containing the values of all of the -** boolean capabilities -** A null byte may be inserted here to make -** sure that the Number Section begins on an -** even word boundary. -** Number Section, containing the values of all of the numeric -** capabilities, each as a short integer -** String Section, containing short integer offsets into the -** String Table, one per string capability -** String Table, containing the actual characters of the string -** capabilities. -** -** NOTE that all short integers in the file are stored using VAX/PDP-style -** byte-order, i.e., least-significant byte first. -** -** There is no structure definition here because it would only confuse -** matters. Terminfo format is a raw byte layout, not a structure -** dump. If you happen to be on a little-endian machine with 16-bit -** shorts that requires no padding between short members in a struct, -** then there is a natural C structure that captures the header, but -** not very helpfully. -*/ - -#define MAGIC 0432 /* first two bytes of a compiled entry */ - -#undef BYTE -#define BYTE(p,n) (unsigned char)((p)[n]) - -#define IS_NEG1(p) ((BYTE(p,0) == 0377) && (BYTE(p,1) == 0377)) -#define IS_NEG2(p) ((BYTE(p,0) == 0376) && (BYTE(p,1) == 0377)) -#define LOW_MSB(p) (BYTE(p,0) + 256*BYTE(p,1)) - -#define IS_TIC_MAGIC(p) (LOW_MSB(p) == MAGIC) - -/* - * The "maximum" here is misleading; XSI guarantees minimum values, which a - * given implementation may exceed. - */ -#define MAX_NAME_SIZE 512 /* maximum legal name field size (XSI:127) */ -#define MAX_ENTRY_SIZE 4096 /* maximum legal entry size */ - -/* - * The maximum size of individual name or alias is guaranteed in XSI to be at - * least 14, since that corresponds to the older filename lengths. Newer - * systems allow longer aliases, though not many terminal descriptions are - * written to use them. The MAX_ALIAS symbol is used for warnings. - */ -#if HAVE_LONG_FILE_NAMES -#define MAX_ALIAS 32 /* smaller than POSIX minimum for PATH_MAX */ -#else -#define MAX_ALIAS 14 /* SVr3 filename length */ -#endif - -/* location of user's personal info directory */ -#define PRIVATE_INFO "%s/.terminfo" /* plug getenv("HOME") into %s */ - -/* - * Some traces are designed to be used via tic's verbose option (and similar in - * infocmp and toe) rather than the 'trace()' function. So we use the bits - * above the normal trace() parameter as a debug-level. - */ - -#define MAX_DEBUG_LEVEL 15 -#define DEBUG_LEVEL(n) ((n) << TRACE_SHIFT) - -#define set_trace_level(n) \ - _nc_tracing &= DEBUG_LEVEL(MAX_DEBUG_LEVEL), \ - _nc_tracing |= DEBUG_LEVEL(n) - -#ifdef TRACE -#define DEBUG(n, a) if (_nc_tracing >= DEBUG_LEVEL(n)) _tracef a -#else -#define DEBUG(n, a) /*nothing*/ -#endif - -extern NCURSES_EXPORT_VAR(unsigned) _nc_tracing; -extern NCURSES_EXPORT(void) _nc_tracef (char *, ...) GCC_PRINTFLIKE(1,2); -extern NCURSES_EXPORT(const char *) _nc_visbuf (const char *); -extern NCURSES_EXPORT(const char *) _nc_visbuf2 (int, const char *); - -/* - * These are the types of tokens returned by the scanner. The first - * three are also used in the hash table of capability names. The scanner - * returns one of these values after loading the specifics into the global - * structure curr_token. - */ - -#define BOOLEAN 0 /* Boolean capability */ -#define NUMBER 1 /* Numeric capability */ -#define STRING 2 /* String-valued capability */ -#define CANCEL 3 /* Capability to be cancelled in following tc's */ -#define NAMES 4 /* The names for a terminal type */ -#define UNDEF 5 /* Undefined */ - -#define NO_PUSHBACK -1 /* used in pushtype to indicate no pushback */ - - /* - * The global structure in which the specific parts of a - * scanned token are returned. - * - */ - -struct token -{ - char *tk_name; /* name of capability */ - int tk_valnumber; /* value of capability (if a number) */ - char *tk_valstring; /* value of capability (if a string) */ -}; - -extern NCURSES_EXPORT_VAR(struct token) _nc_curr_token; - - /* - * Offsets to string capabilities, with the corresponding functionkey - * codes. - */ -struct tinfo_fkeys { - unsigned offset; - chtype code; - }; - -#if BROKEN_LINKER - -#define _nc_tinfo_fkeys _nc_tinfo_fkeysf() -extern NCURSES_EXPORT(const struct tinfo_fkeys *) _nc_tinfo_fkeysf (void); - -#else - -extern NCURSES_EXPORT_VAR(const struct tinfo_fkeys) _nc_tinfo_fkeys[]; - -#endif - -typedef short HashValue; - - /* - * The file comp_captab.c contains an array of these structures, one - * per possible capability. These are indexed by a hash table array of - * pointers to the same structures for use by the parser. - */ - -struct name_table_entry -{ - const char *nte_name; /* name to hash on */ - int nte_type; /* BOOLEAN, NUMBER or STRING */ - HashValue nte_index; /* index of associated variable in its array */ - HashValue nte_link; /* index in table of next hash, or -1 */ -}; - - /* - * Use this structure to hide differences between terminfo and termcap - * tables. - */ -typedef struct { - unsigned table_size; - const HashValue *table_data; - HashValue (*hash_of)(const char *); - int (*compare_names)(const char *, const char *); -} HashData; - -struct alias -{ - const char *from; - const char *to; - const char *source; -}; - -extern NCURSES_EXPORT(const struct name_table_entry *) _nc_get_table (bool); -extern NCURSES_EXPORT(const HashData *) _nc_get_hash_info (bool); -extern NCURSES_EXPORT(const HashValue *) _nc_get_hash_table (bool); -extern NCURSES_EXPORT(const struct alias *) _nc_get_alias_table (bool); - -#define NOTFOUND ((struct name_table_entry *) 0) - -/* out-of-band values for representing absent capabilities */ -#define ABSENT_BOOLEAN ((signed char)-1) /* 255 */ -#define ABSENT_NUMERIC (-1) -#define ABSENT_STRING (char *)0 - -/* out-of-band values for representing cancels */ -#define CANCELLED_BOOLEAN ((signed char)-2) /* 254 */ -#define CANCELLED_NUMERIC (-2) -#define CANCELLED_STRING (char *)(-1) - -#define VALID_BOOLEAN(s) ((unsigned char)(s) <= 1) /* reject "-1" */ -#define VALID_NUMERIC(s) ((s) >= 0) -#define VALID_STRING(s) ((s) != CANCELLED_STRING && (s) != ABSENT_STRING) - -/* termcap entries longer than this may break old binaries */ -#define MAX_TERMCAP_LENGTH 1023 - -/* this is a documented limitation of terminfo */ -#define MAX_TERMINFO_LENGTH 4096 - -#ifndef TERMINFO -#define TERMINFO "/usr/share/terminfo" -#endif - -/* access.c */ -extern NCURSES_EXPORT(unsigned) _nc_pathlast (const char *); -extern NCURSES_EXPORT(bool) _nc_is_abs_path (const char *); -extern NCURSES_EXPORT(bool) _nc_is_dir_path (const char *); -extern NCURSES_EXPORT(bool) _nc_is_file_path (const char *); -extern NCURSES_EXPORT(char *) _nc_basename (char *); -extern NCURSES_EXPORT(char *) _nc_rootname (char *); - -/* comp_hash.c: name lookup */ -extern NCURSES_EXPORT(struct name_table_entry const *) _nc_find_entry - (const char *, const HashValue *); -extern NCURSES_EXPORT(struct name_table_entry const *) _nc_find_type_entry - (const char *, int, bool); - -/* comp_scan.c: lexical analysis */ -extern NCURSES_EXPORT(int) _nc_get_token (bool); -extern NCURSES_EXPORT(void) _nc_panic_mode (char); -extern NCURSES_EXPORT(void) _nc_push_token (int); -extern NCURSES_EXPORT(void) _nc_reset_input (FILE *, char *); -extern NCURSES_EXPORT_VAR(int) _nc_curr_col; -extern NCURSES_EXPORT_VAR(int) _nc_curr_line; -extern NCURSES_EXPORT_VAR(int) _nc_syntax; -extern NCURSES_EXPORT_VAR(long) _nc_comment_end; -extern NCURSES_EXPORT_VAR(long) _nc_comment_start; -extern NCURSES_EXPORT_VAR(long) _nc_curr_file_pos; -extern NCURSES_EXPORT_VAR(long) _nc_start_line; -#define SYN_TERMINFO 0 -#define SYN_TERMCAP 1 - -/* comp_error.c: warning & abort messages */ -extern NCURSES_EXPORT(const char *) _nc_get_source (void); -extern NCURSES_EXPORT(void) _nc_err_abort (const char *const,...) GCC_PRINTFLIKE(1,2) GCC_NORETURN; -extern NCURSES_EXPORT(void) _nc_get_type (char *name); -extern NCURSES_EXPORT(void) _nc_set_source (const char *const); -extern NCURSES_EXPORT(void) _nc_set_type (const char *const); -extern NCURSES_EXPORT(void) _nc_syserr_abort (const char *const,...) GCC_PRINTFLIKE(1,2) GCC_NORETURN; -extern NCURSES_EXPORT(void) _nc_warning (const char *const,...) GCC_PRINTFLIKE(1,2); -extern NCURSES_EXPORT_VAR(bool) _nc_suppress_warnings; - -/* comp_expand.c: expand string into readable form */ -extern NCURSES_EXPORT(char *) _nc_tic_expand (const char *, bool, int); - -/* comp_scan.c: decode string from readable form */ -extern NCURSES_EXPORT(int) _nc_trans_string (char *, char *); - -/* captoinfo.c: capability conversion */ -extern NCURSES_EXPORT(char *) _nc_captoinfo (const char *, const char *, int const); -extern NCURSES_EXPORT(char *) _nc_infotocap (const char *, const char *, int const); - -/* home_terminfo.c */ -extern NCURSES_EXPORT(char *) _nc_home_terminfo (void); - -/* lib_tparm.c */ -#define NUM_PARM 9 - -extern NCURSES_EXPORT_VAR(int) _nc_tparm_err; - -extern NCURSES_EXPORT(int) _nc_tparm_analyze(const char *, char **, int *); - -/* lib_tputs.c */ -extern NCURSES_EXPORT_VAR(int) _nc_nulls_sent; /* Add one for every null sent */ - -/* comp_main.c: compiler main */ -extern const char * _nc_progname; - -/* db_iterator.c */ -typedef enum { - dbdTIC = 0, -#if USE_DATABASE - dbdEnvOnce, - dbdHome, - dbdEnvList, - dbdCfgList, - dbdCfgOnce, -#endif -#if USE_TERMCAP - dbdEnvOnce2, - dbdEnvList2, - dbdCfgList2, -#endif - dbdLAST -} DBDIRS; - -extern NCURSES_EXPORT(const char *) _nc_next_db(DBDIRS *, int *); -extern NCURSES_EXPORT(const char *) _nc_tic_dir (const char *); -extern NCURSES_EXPORT(void) _nc_first_db(DBDIRS *, int *); -extern NCURSES_EXPORT(void) _nc_last_db(void); - -/* write_entry.c */ -extern NCURSES_EXPORT(int) _nc_tic_written (void); - -#ifdef __cplusplus -} -#endif - -#endif /* __TIC_H */ diff --git a/windows/ncurses/include/ncurses/unctrl.h b/windows/ncurses/include/ncurses/unctrl.h deleted file mode 100644 index 318de7b57..000000000 --- a/windows/ncurses/include/ncurses/unctrl.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** - * Copyright (c) 1998-2008,2009 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ - -/**************************************************************************** - * Author: Zeyd M. Ben-Halim 1992,1995 * - * and: Eric S. Raymond * - ****************************************************************************/ - -/* - * unctrl.h - * - * Display a printable version of a control character. - * Control characters are displayed in caret notation (^x), DELETE is displayed - * as ^?. Printable characters are displayed as is. - */ - -/* $Id: unctrl.h.in,v 1.11 2009/04/18 21:00:52 tom Exp $ */ - -#ifndef NCURSES_UNCTRL_H_incl -#define NCURSES_UNCTRL_H_incl 1 - -#undef NCURSES_VERSION -#define NCURSES_VERSION "5.9" - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#undef unctrl -NCURSES_EXPORT(NCURSES_CONST char *) unctrl (chtype); - -#if 1 -NCURSES_EXPORT(NCURSES_CONST char *) NCURSES_SP_NAME(unctrl) (SCREEN*, chtype); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* NCURSES_UNCTRL_H_incl */ diff --git a/windows/ncurses/lib/Win32/libgcc_s_sjlj-1.dll b/windows/ncurses/lib/Win32/libgcc_s_sjlj-1.dll deleted file mode 100644 index 2f0a309f2e8ed2fbeb58b36257f90aa6b0b5a7a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 88085 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 diff --git a/windows/ncurses/lib/Win32/wform.lib b/windows/ncurses/lib/Win32/wform.lib deleted file mode 100644 index 8e36351eb23e086034ddc59c2bcaae428bc60bab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20764 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 diff --git a/windows/ncurses/lib/Win32/wmenu.lib b/windows/ncurses/lib/Win32/wmenu.lib deleted file mode 100644 index 1b129ce6314837d4d1f6dbf802e4f00dba9fe08b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17014 zcmc&*OKe<47QOi}fFZ$z|1WV8LlP45aoWFp9p?iMwi9f_NF&5cr`<^!>~2rHodBEJ zA%qZOjaVR!gb=%t5F@cb2(e-$25DFz#ANoY5JK!m%(=Jf-KzJxyZqYE*0gl|s&3s^ zr#`nnw_bVsv0}Y+?L^msp5*V);o+g-!QsBba8iEIMi2K76io0^7ZH6x^ynPX)^~`u zeMz*v+u~h3fgKwy>UiEH+IimMGdzLbUJJb63p|eZ1#jWW_|@Qvmxu)45bf#%-Xq$* z-r{9E8Q&W086Xn8k0XkMIQgwphH5Cj;%oIDF3HQ#^qJ+Dh;?o{XOj z`d=Ute2ynDu*2dFJQ+V33{DXVpfd;zAwR)ecrt!77`{X#_!>{(NWlVabObosWr4aM zW!yA4cAiM^37)|5trlr4_U z?#)`YS}rxD9E+AWB~slpCYDc_R&n~3#ZoFSRO?K$)V)zJ-iT~Atm;Ko zXS`B<#V>9mu38htM(J8K$*pnvTCrX%HOlp9tZLeOvN&Hhb0fiwMA`0)X|Ts&h#~KxOVWPs>3!Im6qy@wR*HrvwhbrwEFW= zG=0%^8lp3&MyJRAbT%PdY|Ji}>ahr!a|NS{)G!${wtS^tF56@;=%sOaD3UZ2G-;e; zRH`ji8zisCVJ~&IjFMCq8kJhr>LetdW~Dk?e%0#Oa3Zx5lT@l4^wO$g2T~Xl^wMez z4YaAGnP4g{s$IF_rJHDzPF!}*BI25O8n8$hjxd;@m$tN6t}isu6OybkPvd%VZV5&# z={D@ARu(Il=QKTz84WR#%f-?w6nQ}}ZMI&yUIw|O#t|?5O0ABpCDjCzY4b%ibDSy> zFa2u0{F+TQK`+g8ki6;ll@Y*X&>?=q+{+gt!w5&;>j>6P`!r8MI#QHw8c_!u51(iuuUyDc%t>@!o?XA2d&o)NZm&xlY)y1wC!drxLZd$S}} zCLNcmsgkrNk5Q-PMy$%5#Yi#zk*hjtAI*{!pNw7A@ci<6xxs9lMJJGwqMtCZ9;3jZ>C(&mBdxY-*-H#K! z1^f!U^aRm2K;JH+_ki`giCzZ21qSvIy${^>BvBRk4mh$Gjw#T!5BUS%10zoneF$vc zPt*W@1V#@KeGGKN1Gx_T2#g*g`Uu$4NAx;y6F7I6=u@D#K=d~7Gw?z`(dWR90irj6 zpMa@B$bjAu5b~q+93@bSvFPw^JA0L3h$7+Dvy*H{DHJ=pMS4?xXwZ z0eX-gqKD}bdXyfct+b7LXglqoozzQ@(-X9dcGDhulJ?R*dW!bb0Xj&BsE-a)f%<8H z25E?f=?ERAV|1KO&`BDhQ#4Aa=?tBvbM!PlLt}KFo~3b`ph>zw7wI{gqG_73B}|v@ z|6i^RSWP?j9XoOo)faI7WHv8PUyNP1FMPMITx>6+m$}R%GMO5Ioh$n2ZzxT4% zUA-sEzGL@ZN-gtJ0NIdxI(~PELaIAN=B>=_ch)9TPB%o@PaDzlJ7%MoWov9TGwgg* zntnZbchSo9RGu(D-Jh79tIJoa8QhzubOU?OlxD)-v;e-%snEAO6$UqqDXx^2Xda%W zs4U%ztt>{BJ*#0^YO9ut`kS?k=aX1S+N?~RlIduW*CKCSK{RpRhj^B?1ZtDZ9Nzis z2h{zQ15s&4<6xS@wxmDk&G_C~msqfW%9WVkB{g|=r6*NpHWv+JJsLFgl^4ZKB{9?S z64VJoVs@yQa6Cs#eY_)}cwY8KOdOQCSR!V0NYKo`CTM0}2^;&DpeeTon+{px(*YR> zqNcN|#G2;Qgw#9x(9t0Z?l{9VhzPYoBqmnxX32OyOdT#X&501iev3a3^1w+N152c} zO(SX4w1`Gc`829!REh04j!U^yetEMCEb&B-1Av_^fA!3{fyahn+@6n znI1Q){sn?in*~M{&OXeKjgUu`|MNx_&PvRW_5K-0>~j^{HcNXx0@^kv*lBAH3|a$3 zYmyAf@pU{;;W!EBGTd$0mbl&380Pcl@5o9@9gl$if!6%J;N~7p@q6bEj#NV#N1eM9 zlB_eEDNiqkGqG<}iq31OLp;^OI7q}qxz4b~2O-?PTHf^!j?O#O#ikBMzy*%UL$PSkVqa_}8)V?XzRYqJ^e=Cm;fMsH1ic$L!dr)a~~z#EJviFto3PQ3-^Iz3-dT{ zUb9|7Z2~N81>U8YJS=TyiTlC8drjkrnllJTqoJ%V7FfNw)eMV&x}gjmuU>^fjks2^ zYt46la3qEku<$4~EOM5yMl8Gr8y4~C^RNU~d0u}ViyZajVG7Ix zyutRFs$TafWmc;W^bYR<4UZgMXx1y32LiPb_e+k7;u8@^q@k>}35*+dwoPr!nUd!1 zS}!Y0pf zXW?_gJUoHguy<(sMvfoXhy_&+P(P${^s0p+fuA5jEIfB)! zS1{8ASa6ZWvaIDgfNL@y%UZ4j>;)M+ok8!Q4YT3?5fiF?xxKNGVh`JV@uOT={#HkYsMu-|H^e9mcVL_E0Fk{>F#km z8VzNgs{`IHE?An6rmJ-p5%8*Tfzxn_hmd=x6JWv>QIBaYcL>K5Ou1*bKu_U{t5>I0 znBf9v&nFXHxqYlaPmRP(tKilzT=B>>Hm+Fy-9k2j-)(6i?ore(3Av`2^Q0?1uyG z$G1-0H6p(DqwB2;WnFm#7BQaSS<97UBEhr@D@UO9; acwZU%wsnztR)M1ssLONA;ol1L>heGA`A&lX diff --git a/windows/ncurses/lib/Win32/wncurses.dll b/windows/ncurses/lib/Win32/wncurses.dll deleted file mode 100644 index f252bd22851e28218db7357b43dae7cefb51ca8e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 432882 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

RJTRP1MlVH? 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�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 diff --git a/windows/ncurses/lib/Win32/wncurses.lib b/windows/ncurses/lib/Win32/wncurses.lib deleted file mode 100644 index b0ce657a3799d4071f32a88c74c29beeebc825db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123366 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 diff --git a/windows/ncurses/lib/Win32/wpanel.dll b/windows/ncurses/lib/Win32/wpanel.dll deleted file mode 100644 index d1c5bbdf77984cc66de8d718fffcafbd3f999669..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40517 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 XRxa47JxlnYZXfO_Bll?WsN}x^$|#2D diff --git a/windows/ncurses/lib/Win32/wpanel.lib b/windows/ncurses/lib/Win32/wpanel.lib deleted file mode 100644 index 5fcdfb6072d271113bb381c120b2145eb1008cbc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5050 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 E5 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 Bj|>0+ diff --git a/windows/ncurses/lib/x64/wform.lib b/windows/ncurses/lib/x64/wform.lib deleted file mode 100644 index 1c5fc56001c38f69a379e4b3adc295636f9c0be7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20002 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 UnzN-zZnwa0e;PdQ4QfmCUz*F9hX4Qo diff --git a/windows/ncurses/lib/x64/wmenu.dll b/windows/ncurses/lib/x64/wmenu.dll deleted file mode 100644 index bf11c2978b5edb87526ef5f361f8043fc0ac8a1d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67812 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¬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 SRF&msiHyuEh^4^?lm7$$MGc7n diff --git a/windows/ncurses/lib/x64/wpanel.dll b/windows/ncurses/lib/x64/wpanel.dll deleted file mode 100644 index 42c0ff75247e4041dea1984ffa7bec717b9144eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45915 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 KMkI^9D*qpYGb5V- diff --git a/windows/ncurses/lib/x64/wpanel.lib b/windows/ncurses/lib/x64/wpanel.lib deleted file mode 100644 index ff689e449c7c492f43d21ce1daf4cbfd09bc82a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4828 zcmcIo%}-lL5dX!rgc=NnB>j+D)s>=zUR*v*WTL8a+EgkEA;b`g+l%e@3YLuDlWoee zH%=V#C*;sSqNj-7IaE=Pt(3nYhn%7un$CE3y}Pw}dD!Ghxc5%=JtcKcNkTgK?9z*@o0U$pO0TfK-k+qJ=(bE-MzDYhhC`fM_x7Tbi#d4)^G;G zuLbo+y}7Fd+>uE5K|^s3C7j(>c+m6}(-{bVukHtmYmvg+4}Z}-ixgfnI8?70N;utP zc$F%>44byO)u0g`Dz4Brmp0-DO~qCNn}5&_T2ZH^1oX(3IIK7Qo&q%xek+I?m6|@5 zI}(X@(2 z5^?@75)uVx`nfHnUCy41@m~>3;GZHG?}{ShI3)X;V@o&r82dSy#j=@|H;kR^tYF(l zXeau$J%pt!;YMx$>8)TiCw9)&A5mvzXi408ztNDGdsihZtm>NfIPD*e;g5%vt@I_T zWfUF!Hts3D zgIJjN!2pVBrYJE`{4-^g&<<+heneZ%l>fooxAq$(3f@}^`otwlIXttcXS!z-JxZp) zG9+STR?G~~f5|`U;kAIG8Zk;?lYWQEE*Iq`OT9*jy(HE3lHa>KLnixv zg%#cXyLvt&9c)9lxR}-Lgq2X!;$ThO`*0>Pg=-`&F?Qo@=oCduks%YFW@+$gJ|-QU zYpr@~mbUWm=vt^{#6&1v5&n1MGOG^}p)n`ozQSqvEJcPK{X}%Zf!j-()rUAy@4pQ< zyKxPqD-`<< Qa5beXtgDGHKi0AS1KzZzHvj+t diff --git a/windows/patches/icu/0001-Upgrade-projects-to-VS2013.patch b/windows/patches/icu/0001-Upgrade-projects-to-VS2013.patch deleted file mode 100644 index 53ab005f5..000000000 --- a/windows/patches/icu/0001-Upgrade-projects-to-VS2013.patch +++ /dev/null @@ -1,2279 +0,0 @@ -From f0d00332540713c5d3e3981a5a29dc0ae226d999 Mon Sep 17 00:00:00 2001 -From: Tim Hughes -Date: Mon, 21 Apr 2014 12:54:15 +0100 -Subject: [PATCH 1/3] Upgrade projects to VS2013 . - -Signed-off-by: Tim Hughes ---- - source/common/common.vcxproj | 42 ++- - source/extra/uconv/uconv.vcxproj | 8 +- - source/i18n/i18n.vcxproj | 48 +-- - source/i18n/i18n.vcxproj.filters | 3 +- - source/io/io.vcxproj | 8 +- - source/layout/layout.vcxproj | 8 +- - source/layoutex/layoutex.vcxproj | 8 +- - source/samples/cal/cal.vcxproj | 528 +++++++++++++++++---------------- - source/samples/date/date.vcxproj | 8 +- - source/stubdata/stubdata.vcxproj | 42 ++- - source/test/cintltst/cintltst.vcxproj | 8 +- - source/test/intltest/intltest.vcxproj | 38 +-- - source/test/iotest/iotest.vcxproj | 8 +- - source/test/letest/letest.vcxproj | 8 +- - source/tools/ctestfw/ctestfw.vcxproj | 8 +- - source/tools/genbrk/genbrk.vcxproj | 8 +- - source/tools/genccode/genccode.vcxproj | 8 +- - source/tools/gencfu/gencfu.vcxproj | 8 +- - source/tools/gencmn/gencmn.vcxproj | 8 +- - source/tools/gencnval/gencnval.vcxproj | 8 +- - source/tools/gendict/gendict.vcxproj | 8 +- - source/tools/gennorm2/gennorm2.vcxproj | 8 +- - source/tools/genrb/derb.vcxproj | 8 +- - source/tools/genrb/genrb.vcxproj | 8 +- - source/tools/gensprep/gensprep.vcxproj | 8 +- - source/tools/gentest/gentest.vcxproj | 8 +- - source/tools/icuinfo/icuinfo.vcxproj | 8 +- - source/tools/icuinfo/testplug.vcxproj | 8 +- - source/tools/icupkg/icupkg.vcxproj | 8 +- - source/tools/makeconv/makeconv.vcxproj | 8 +- - source/tools/pkgdata/pkgdata.vcxproj | 8 +- - source/tools/toolutil/toolutil.vcxproj | 10 +- - 32 files changed, 531 insertions(+), 380 deletions(-) - -diff --git a/source/common/common.vcxproj b/source/common/common.vcxproj -index ef0dfc1..0b1eab3 100644 ---- a/source/common/common.vcxproj -+++ b/source/common/common.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -26,21 +26,25 @@ - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - -@@ -65,17 +69,33 @@ - - <_ProjectFileVersion>10.0.30319.1 - .\..\..\lib\ -- .\x86\Release\ -+ x86\$(Configuration) - false - .\..\..\lib\ -- .\x86\Debug\ -- true -+ x86\$(Configuration) -+ false - .\x64\Release\ -- .\x64\Release\ -+ x64\$(Configuration) - false - .\x64\Debug\ -- .\x64\Debug\ -- true -+ x64\$(Configuration) -+ false -+ -+ -+ icuuc52d -+ ..\..\bin -+ -+ -+ icuuc52 -+ ..\..\bin -+ -+ -+ icuuc52d -+ ..\..\bin64 -+ -+ -+ icuuc52 -+ ..\..\bin64 - - - -@@ -104,7 +124,6 @@ - 0x0409 - - -- ..\..\bin\icuuc52.dll - true - .\..\..\lib\icuuc.pdb - true -@@ -135,7 +154,6 @@ - .\x86\Debug/ - .\x86\Debug/ - .\x86\Debug/ -- true - Level3 - true - EditAndContinue -@@ -145,7 +163,6 @@ - 0x0409 - - -- ..\..\bin\icuuc52d.dll - true - true - .\..\..\lib\icuucd.pdb -@@ -183,7 +200,6 @@ - 0x0409 - - -- ..\..\bin64\icuuc52.dll - true - .\..\..\lib64\icuuc.pdb - true -@@ -212,7 +228,6 @@ - .\x64\Debug/ - .\x64\Debug/ - .\x64\Debug/ -- true - Level3 - true - ProgramDatabase -@@ -222,7 +237,6 @@ - 0x0409 - - -- ..\..\bin64\icuuc52d.dll - true - true - .\..\..\lib64\icuucd.pdb -@@ -1751,4 +1765,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/extra/uconv/uconv.vcxproj b/source/extra/uconv/uconv.vcxproj -index 3ff795c..1e9829f 100644 ---- a/source/extra/uconv/uconv.vcxproj -+++ b/source/extra/uconv/uconv.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -26,21 +26,25 @@ - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - -@@ -292,4 +296,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/i18n/i18n.vcxproj b/source/i18n/i18n.vcxproj -index 3c1eebb..3f216cc 100644 ---- a/source/i18n/i18n.vcxproj -+++ b/source/i18n/i18n.vcxproj -@@ -1,5 +1,5 @@ -- -- -+ -+ - - - Debug -@@ -26,21 +26,25 @@ - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - -@@ -64,18 +68,30 @@ - - - <_ProjectFileVersion>10.0.30319.1 -- .\..\..\lib\ -- .\x86\Release\ -+ ..\..\bin -+ x86\$(Configuration) - false -- .\..\..\lib\ -- .\x86\Debug\ -- true -- .\x64\Release\ -- .\x64\Release\ -+ ..\..\bin -+ x86\$(Configuration) -+ false -+ ..\..\bin64 -+ x64\$(Configuration) - false -- .\x64\Debug\ -- .\x64\Debug\ -- true -+ ..\..\bin64 -+ x64\$(Configuration) -+ false -+ -+ -+ icuin52d -+ -+ -+ icuin52 -+ -+ -+ icuin52d -+ -+ -+ icuin52 - - - -@@ -107,7 +123,6 @@ - ../common;%(AdditionalIncludeDirectories) - - -- ..\..\bin\icuin52.dll - true - .\..\..\lib\icuin.pdb - true -@@ -139,7 +154,6 @@ - .\x86\Debug/ - .\x86\Debug/ - .\x86\Debug/ -- true - Level3 - true - EditAndContinue -@@ -151,7 +165,6 @@ - ../common;%(AdditionalIncludeDirectories) - - -- ..\..\bin\icuin52d.dll - true - true - .\..\..\lib\icuind.pdb -@@ -192,7 +205,6 @@ - ../common;%(AdditionalIncludeDirectories) - - -- ..\..\bin64\icuin52.dll - true - .\..\..\lib64\icuin.pdb - true -@@ -222,7 +234,6 @@ - .\x64\Debug/ - .\x64\Debug/ - .\x64\Debug/ -- true - Level3 - true - ProgramDatabase -@@ -234,7 +245,6 @@ - ../common;%(AdditionalIncludeDirectories) - - -- ..\..\bin64\icuin52d.dll - true - true - .\..\..\lib64\icuind.pdb -@@ -1625,4 +1635,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/i18n/i18n.vcxproj.filters b/source/i18n/i18n.vcxproj.filters -index da3b9aa..554a235 100644 ---- a/source/i18n/i18n.vcxproj.filters -+++ b/source/i18n/i18n.vcxproj.filters -@@ -1050,5 +1050,6 @@ - - misc - -+ - -- -+ -\ No newline at end of file -diff --git a/source/io/io.vcxproj b/source/io/io.vcxproj -index 8944e2a..7b5e178 100644 ---- a/source/io/io.vcxproj -+++ b/source/io/io.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -26,21 +26,25 @@ - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - -@@ -319,4 +323,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/layout/layout.vcxproj b/source/layout/layout.vcxproj -index d80eb54..90a5e42 100644 ---- a/source/layout/layout.vcxproj -+++ b/source/layout/layout.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -26,21 +26,25 @@ - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - -@@ -576,4 +580,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/layoutex/layoutex.vcxproj b/source/layoutex/layoutex.vcxproj -index dac4cfe..f2c8dd8 100644 ---- a/source/layoutex/layoutex.vcxproj -+++ b/source/layoutex/layoutex.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -27,21 +27,25 @@ - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - -@@ -327,4 +331,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/samples/cal/cal.vcxproj b/source/samples/cal/cal.vcxproj -index 13dae70..947e173 100644 ---- a/source/samples/cal/cal.vcxproj -+++ b/source/samples/cal/cal.vcxproj -@@ -1,264 +1,268 @@ -- -- -- -- -- Debug -- Win32 -- -- -- Debug -- x64 -- -- -- Release -- Win32 -- -- -- Release -- x64 -- -- -- -- {F7659D77-09CF-4FE9-ACEE-927287AA9509} -- -- -- -- Application -- false -- MultiByte -- -- -- Application -- false -- MultiByte -- -- -- Application -- false -- MultiByte -- -- -- Application -- false -- MultiByte -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- <_ProjectFileVersion>10.0.30319.1 -- .\x86\Release\ -- .\x86\Release\ -- false -- .\x64\Release\ -- .\x64\Release\ -- false -- .\x86\Debug\ -- .\x86\Debug\ -- true -- .\x64\Debug\ -- .\x64\Debug\ -- true -- -- -- -- .\x86\Release/cal.tlb -- -- -- OnlyExplicitInline -- ..\..\..\include;%(AdditionalIncludeDirectories) -- WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) -- true -- MultiThreadedDLL -- true -- true -- -- -- .\x86\Release/cal.pch -- .\x86\Release/ -- .\x86\Release/ -- .\x86\Release/ -- Level3 -- true -- Default -- -- -- NDEBUG;%(PreprocessorDefinitions) -- 0x0409 -- -- -- icuuc.lib;icuin.lib;%(AdditionalDependencies) -- .\x86\Release/cal.exe -- true -- ../../../lib;%(AdditionalLibraryDirectories) -- .\x86\Release/cal.pdb -- Console -- false -- -- -- -- -- -- -- X64 -- .\x64\Release/cal.tlb -- -- -- OnlyExplicitInline -- ..\..\..\include;%(AdditionalIncludeDirectories) -- WIN64;WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) -- true -- MultiThreadedDLL -- true -- true -- -- -- .\x64\Release/cal.pch -- .\x64\Release/ -- .\x64\Release/ -- .\x64\Release/ -- Level3 -- true -- Default -- -- -- NDEBUG;%(PreprocessorDefinitions) -- 0x0409 -- -- -- icuuc.lib;icuin.lib;%(AdditionalDependencies) -- .\x64\Release/cal.exe -- true -- ../../../lib64;%(AdditionalLibraryDirectories) -- .\x64\Release/cal.pdb -- Console -- false -- -- -- MachineX64 -- -- -- -- -- .\x86\Debug/cal.tlb -- -- -- Disabled -- ..\..\..\include;%(AdditionalIncludeDirectories) -- WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) -- EnableFastChecks -- MultiThreadedDebugDLL -- true -- -- -- .\x86\Debug/cal.pch -- .\x86\Debug/ -- .\x86\Debug/ -- .\x86\Debug/ -- true -- Level3 -- true -- EditAndContinue -- Default -- -- -- _DEBUG;%(PreprocessorDefinitions) -- 0x0409 -- -- -- icuucd.lib;icuind.lib;%(AdditionalDependencies) -- .\x86\Debug/cal.exe -- true -- ../../../lib;%(AdditionalLibraryDirectories) -- true -- .\x86\Debug/cal.pdb -- Console -- false -- -- -- -- -- -- -- X64 -- .\x64\Debug/cal.tlb -- -- -- Disabled -- ..\..\..\include;%(AdditionalIncludeDirectories) -- WIN64;WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) -- EnableFastChecks -- MultiThreadedDebugDLL -- true -- -- -- .\x64\Debug/cal.pch -- .\x64\Debug/ -- .\x64\Debug/ -- .\x64\Debug/ -- true -- Level3 -- true -- ProgramDatabase -- Default -- -- -- _DEBUG;%(PreprocessorDefinitions) -- 0x0409 -- -- -- icuucd.lib;icuind.lib;%(AdditionalDependencies) -- .\x64\Debug/cal.exe -- true -- ../../../lib64;%(AdditionalLibraryDirectories) -- true -- .\x64\Debug/cal.pdb -- Console -- false -- -- -- MachineX64 -- -- -- -+ -+ -+ -+ -+ Debug -+ Win32 -+ -+ -+ Debug -+ x64 -+ -+ -+ Release -+ Win32 -+ -+ -+ Release -+ x64 -+ -+ -+ -+ {F7659D77-09CF-4FE9-ACEE-927287AA9509} -+ -+ -+ -+ Application -+ false -+ MultiByte -+ v120 -+ -+ -+ Application -+ false -+ MultiByte -+ v120 -+ -+ -+ Application -+ false -+ MultiByte -+ v120 -+ -+ -+ Application -+ false -+ MultiByte -+ v120 -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ <_ProjectFileVersion>10.0.30319.1 -+ .\x86\Release\ -+ .\x86\Release\ -+ false -+ .\x64\Release\ -+ .\x64\Release\ -+ false -+ .\x86\Debug\ -+ .\x86\Debug\ -+ true -+ .\x64\Debug\ -+ .\x64\Debug\ -+ true -+ -+ -+ -+ .\x86\Release/cal.tlb -+ -+ -+ OnlyExplicitInline -+ ..\..\..\include;%(AdditionalIncludeDirectories) -+ WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) -+ true -+ MultiThreadedDLL -+ true -+ true -+ -+ -+ .\x86\Release/cal.pch -+ .\x86\Release/ -+ .\x86\Release/ -+ .\x86\Release/ -+ Level3 -+ true -+ Default -+ -+ -+ NDEBUG;%(PreprocessorDefinitions) -+ 0x0409 -+ -+ -+ icuuc.lib;icuin.lib;%(AdditionalDependencies) -+ .\x86\Release/cal.exe -+ true -+ ../../../lib;%(AdditionalLibraryDirectories) -+ .\x86\Release/cal.pdb -+ Console -+ false -+ -+ -+ -+ -+ -+ -+ X64 -+ .\x64\Release/cal.tlb -+ -+ -+ OnlyExplicitInline -+ ..\..\..\include;%(AdditionalIncludeDirectories) -+ WIN64;WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) -+ true -+ MultiThreadedDLL -+ true -+ true -+ -+ -+ .\x64\Release/cal.pch -+ .\x64\Release/ -+ .\x64\Release/ -+ .\x64\Release/ -+ Level3 -+ true -+ Default -+ -+ -+ NDEBUG;%(PreprocessorDefinitions) -+ 0x0409 -+ -+ -+ icuuc.lib;icuin.lib;%(AdditionalDependencies) -+ .\x64\Release/cal.exe -+ true -+ ../../../lib64;%(AdditionalLibraryDirectories) -+ .\x64\Release/cal.pdb -+ Console -+ false -+ -+ -+ MachineX64 -+ -+ -+ -+ -+ .\x86\Debug/cal.tlb -+ -+ -+ Disabled -+ ..\..\..\include;%(AdditionalIncludeDirectories) -+ WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) -+ EnableFastChecks -+ MultiThreadedDebugDLL -+ true -+ -+ -+ .\x86\Debug/cal.pch -+ .\x86\Debug/ -+ .\x86\Debug/ -+ .\x86\Debug/ -+ true -+ Level3 -+ true -+ EditAndContinue -+ Default -+ -+ -+ _DEBUG;%(PreprocessorDefinitions) -+ 0x0409 -+ -+ -+ icuucd.lib;icuind.lib;%(AdditionalDependencies) -+ .\x86\Debug/cal.exe -+ true -+ ../../../lib;%(AdditionalLibraryDirectories) -+ true -+ .\x86\Debug/cal.pdb -+ Console -+ false -+ -+ -+ -+ -+ -+ -+ X64 -+ .\x64\Debug/cal.tlb -+ -+ -+ Disabled -+ ..\..\..\include;%(AdditionalIncludeDirectories) -+ WIN64;WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) -+ EnableFastChecks -+ MultiThreadedDebugDLL -+ true -+ -+ -+ .\x64\Debug/cal.pch -+ .\x64\Debug/ -+ .\x64\Debug/ -+ .\x64\Debug/ -+ true -+ Level3 -+ true -+ ProgramDatabase -+ Default -+ -+ -+ _DEBUG;%(PreprocessorDefinitions) -+ 0x0409 -+ -+ -+ icuucd.lib;icuind.lib;%(AdditionalDependencies) -+ .\x64\Debug/cal.exe -+ true -+ ../../../lib64;%(AdditionalLibraryDirectories) -+ true -+ .\x64\Debug/cal.pdb -+ Console -+ false -+ -+ -+ MachineX64 -+ -+ -+ - -- false -- -+ false -+ - -- false -- -- -- -- -- -- -- -- {73c0a65b-d1f2-4de1-b3a6-15dad2c23f3d} -- false -- -- -- {0178b127-6269-407d-b112-93877bb62776} -- false -- -- -- -- -- -- -+ false -+ -+ -+ -+ -+ -+ -+ -+ {73c0a65b-d1f2-4de1-b3a6-15dad2c23f3d} -+ false -+ -+ -+ {0178b127-6269-407d-b112-93877bb62776} -+ false -+ -+ -+ -+ -+ -+ -\ No newline at end of file -diff --git a/source/samples/date/date.vcxproj b/source/samples/date/date.vcxproj -index 0632b3f..38d70a9 100644 ---- a/source/samples/date/date.vcxproj -+++ b/source/samples/date/date.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -26,21 +26,25 @@ - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - -@@ -255,4 +259,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/stubdata/stubdata.vcxproj b/source/stubdata/stubdata.vcxproj -index ed4ca6b..541f19f 100644 ---- a/source/stubdata/stubdata.vcxproj -+++ b/source/stubdata/stubdata.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -26,21 +26,25 @@ - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - -@@ -64,21 +68,35 @@ - - - <_ProjectFileVersion>10.0.30319.1 -- .\x86\Release\ -- .\x86\Release\ -+ ..\..\bin - false - false -- .\x86\Debug\ -- .\x86\Debug\ -+ ..\..\bin - false -- .\x64\Release\ -- .\x64\Release\ -+ ..\..\bin64 - false - false -- .\x64\Debug\ -- .\x64\Debug\ -+ ..\..\bin64 - false - -+ -+ icudt52d -+ x86\$(Configuration) -+ false -+ -+ -+ icudt52d -+ x64\$(Configuration) -+ false -+ -+ -+ icudt52 -+ x86\$(Configuration) -+ -+ -+ icudt52 -+ x64\$(Configuration) -+ - - - NDEBUG;%(PreprocessorDefinitions) -@@ -113,7 +131,6 @@ - echo "File with stubdata build time, used as a dependency to trigger fresh data build, since stubdata dll will overwrite the real one." > "$(ProjectDir)stubdatabuilt.txt" - - -- ..\..\bin\icudt52.dll - true - true - .\x86\Release\icudt.pdb -@@ -160,7 +177,6 @@ - echo "File with stubdata build time, used as a dependency to trigger fresh data build, since stubdata dll will overwrite the real one." > "$(ProjectDir)stubdatabuilt.txt" - - -- ..\..\bin\icudt52.dll - true - .\x86\Debug/icudt.pdb - true -@@ -207,7 +223,6 @@ - echo "File with stubdata build time, used as a dependency to trigger fresh data build, since stubdata dll will overwrite the real one." > "$(ProjectDir)stubdatabuilt.txt" - - -- ..\..\bin64\icudt52.dll - true - true - .\x64\Release\icudt.pdb -@@ -252,7 +267,6 @@ - echo "File with stubdata build time, used as a dependency to trigger fresh data build, since stubdata dll will overwrite the real one." > "$(ProjectDir)stubdatabuilt.txt" - - -- ..\..\bin64\icudt52.dll - true - .\x64\Debug/icudt.pdb - true -@@ -277,4 +291,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/test/cintltst/cintltst.vcxproj b/source/test/cintltst/cintltst.vcxproj -index 17529b6..f04da0c 100644 ---- a/source/test/cintltst/cintltst.vcxproj -+++ b/source/test/cintltst/cintltst.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -26,21 +26,25 @@ - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - -@@ -373,4 +377,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/test/intltest/intltest.vcxproj b/source/test/intltest/intltest.vcxproj -index 8a6698e..9ee9bc7 100644 ---- a/source/test/intltest/intltest.vcxproj -+++ b/source/test/intltest/intltest.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -27,21 +27,25 @@ - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - -@@ -229,7 +233,7 @@ - - - -- false -+ false - - - -@@ -260,7 +264,7 @@ - - - -- false -+ false - - - false -@@ -276,7 +280,7 @@ - - - -- false -+ false - - - -@@ -284,7 +288,7 @@ - - - -- false -+ false - - - -@@ -326,13 +330,13 @@ - - - -- false -+ false - - - - - -- false -+ false - - - false -@@ -351,7 +355,7 @@ - - - -- false -+ false - - - -@@ -360,35 +364,35 @@ - - - -- false -+ false - - -- false -+ false - - -- false -+ false - - - - - -- false -+ false - - - - -- false -+ false - - -- false -+ false - - -- false -+ false - - - - -- false -+ false - - - -@@ -561,4 +565,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/test/iotest/iotest.vcxproj b/source/test/iotest/iotest.vcxproj -index 0d39d29..5172208 100644 ---- a/source/test/iotest/iotest.vcxproj -+++ b/source/test/iotest/iotest.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -26,21 +26,25 @@ - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - -@@ -259,4 +263,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/test/letest/letest.vcxproj b/source/test/letest/letest.vcxproj -index a71d629..be01399 100644 ---- a/source/test/letest/letest.vcxproj -+++ b/source/test/letest/letest.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -26,21 +26,25 @@ - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - -@@ -274,4 +278,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/tools/ctestfw/ctestfw.vcxproj b/source/tools/ctestfw/ctestfw.vcxproj -index 7dbdc9f..9281a1b 100644 ---- a/source/tools/ctestfw/ctestfw.vcxproj -+++ b/source/tools/ctestfw/ctestfw.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -26,21 +26,25 @@ - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - -@@ -280,4 +284,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/tools/genbrk/genbrk.vcxproj b/source/tools/genbrk/genbrk.vcxproj -index 73e5372..8ae2620 100644 ---- a/source/tools/genbrk/genbrk.vcxproj -+++ b/source/tools/genbrk/genbrk.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -26,21 +26,25 @@ - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - -@@ -255,4 +259,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/tools/genccode/genccode.vcxproj b/source/tools/genccode/genccode.vcxproj -index f6fd59d..e1bb8fb 100644 ---- a/source/tools/genccode/genccode.vcxproj -+++ b/source/tools/genccode/genccode.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -26,21 +26,25 @@ - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - -@@ -251,4 +255,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/tools/gencfu/gencfu.vcxproj b/source/tools/gencfu/gencfu.vcxproj -index 18c63a6..315ca7b 100644 ---- a/source/tools/gencfu/gencfu.vcxproj -+++ b/source/tools/gencfu/gencfu.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -27,20 +27,24 @@ - Application - false - MultiByte -+ v120 - - - Application - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - -@@ -238,4 +242,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/tools/gencmn/gencmn.vcxproj b/source/tools/gencmn/gencmn.vcxproj -index 6c83ef4..91f0a64 100644 ---- a/source/tools/gencmn/gencmn.vcxproj -+++ b/source/tools/gencmn/gencmn.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -26,21 +26,25 @@ - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - -@@ -255,4 +259,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/tools/gencnval/gencnval.vcxproj b/source/tools/gencnval/gencnval.vcxproj -index ca12c12..474f1a2 100644 ---- a/source/tools/gencnval/gencnval.vcxproj -+++ b/source/tools/gencnval/gencnval.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -26,21 +26,25 @@ - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - -@@ -255,4 +259,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/tools/gendict/gendict.vcxproj b/source/tools/gendict/gendict.vcxproj -index 6852b44..968f817 100644 ---- a/source/tools/gendict/gendict.vcxproj -+++ b/source/tools/gendict/gendict.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -26,21 +26,25 @@ - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - -@@ -255,4 +259,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/tools/gennorm2/gennorm2.vcxproj b/source/tools/gennorm2/gennorm2.vcxproj -index 4245a0b..bf60570 100644 ---- a/source/tools/gennorm2/gennorm2.vcxproj -+++ b/source/tools/gennorm2/gennorm2.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -27,20 +27,24 @@ - - Application - Unicode -+ v120 - - - Application - Unicode - true -+ v120 - - - Application - Unicode -+ v120 - - - Application - Unicode - true -+ v120 - - - -@@ -263,4 +267,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/tools/genrb/derb.vcxproj b/source/tools/genrb/derb.vcxproj -index b2e27e6..9c14c94 100644 ---- a/source/tools/genrb/derb.vcxproj -+++ b/source/tools/genrb/derb.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -26,21 +26,25 @@ - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - -@@ -278,4 +282,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/tools/genrb/genrb.vcxproj b/source/tools/genrb/genrb.vcxproj -index b7f48ef..ad02f5b 100644 ---- a/source/tools/genrb/genrb.vcxproj -+++ b/source/tools/genrb/genrb.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -26,21 +26,25 @@ - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - -@@ -278,4 +282,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/tools/gensprep/gensprep.vcxproj b/source/tools/gensprep/gensprep.vcxproj -index 533b546..fad1e63 100644 ---- a/source/tools/gensprep/gensprep.vcxproj -+++ b/source/tools/gensprep/gensprep.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -26,21 +26,25 @@ - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - -@@ -257,4 +261,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/tools/gentest/gentest.vcxproj b/source/tools/gentest/gentest.vcxproj -index f8fb903..96a8b15 100644 ---- a/source/tools/gentest/gentest.vcxproj -+++ b/source/tools/gentest/gentest.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -27,21 +27,25 @@ - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - -@@ -244,4 +248,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/tools/icuinfo/icuinfo.vcxproj b/source/tools/icuinfo/icuinfo.vcxproj -index 6da52ed..864b5e7 100644 ---- a/source/tools/icuinfo/icuinfo.vcxproj -+++ b/source/tools/icuinfo/icuinfo.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -28,21 +28,25 @@ - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - -@@ -256,4 +260,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/tools/icuinfo/testplug.vcxproj b/source/tools/icuinfo/testplug.vcxproj -index edf6858..cc5a0ec 100644 ---- a/source/tools/icuinfo/testplug.vcxproj -+++ b/source/tools/icuinfo/testplug.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -26,21 +26,25 @@ - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - -@@ -255,4 +259,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/tools/icupkg/icupkg.vcxproj b/source/tools/icupkg/icupkg.vcxproj -index b3c762c..606276d 100644 ---- a/source/tools/icupkg/icupkg.vcxproj -+++ b/source/tools/icupkg/icupkg.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -27,21 +27,25 @@ - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - -@@ -244,4 +248,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/tools/makeconv/makeconv.vcxproj b/source/tools/makeconv/makeconv.vcxproj -index 110dee9..3d302d3 100644 ---- a/source/tools/makeconv/makeconv.vcxproj -+++ b/source/tools/makeconv/makeconv.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -26,21 +26,25 @@ - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - -@@ -260,4 +264,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/tools/pkgdata/pkgdata.vcxproj b/source/tools/pkgdata/pkgdata.vcxproj -index 18fa39d..b2d72bd 100644 ---- a/source/tools/pkgdata/pkgdata.vcxproj -+++ b/source/tools/pkgdata/pkgdata.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -26,21 +26,25 @@ - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - Application - false - MultiByte -+ v120 - - - -@@ -271,4 +275,4 @@ - - - -- -+ -\ No newline at end of file -diff --git a/source/tools/toolutil/toolutil.vcxproj b/source/tools/toolutil/toolutil.vcxproj -index 8cb1277..5574582 100644 ---- a/source/tools/toolutil/toolutil.vcxproj -+++ b/source/tools/toolutil/toolutil.vcxproj -@@ -1,5 +1,5 @@ -  -- -+ - - - Debug -@@ -26,21 +26,25 @@ - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - DynamicLibrary - false - MultiByte -+ v120 - - - -@@ -267,7 +271,7 @@ - - - -- false -+ false - - - false -@@ -328,4 +332,4 @@ - - - -- -+ -\ No newline at end of file --- -1.9.0.msysgit.0 - diff --git a/windows/patches/icu/0002-Qt-requires-U_CHARSET_IS_UTF8-1.patch b/windows/patches/icu/0002-Qt-requires-U_CHARSET_IS_UTF8-1.patch deleted file mode 100644 index 5b9f3e959..000000000 --- a/windows/patches/icu/0002-Qt-requires-U_CHARSET_IS_UTF8-1.patch +++ /dev/null @@ -1,26 +0,0 @@ -From fca4313ae7ac54ebb5a6f3b46451306223b53aeb Mon Sep 17 00:00:00 2001 -From: Tim Hughes -Date: Mon, 21 Apr 2014 13:33:29 +0100 -Subject: [PATCH 2/3] Qt requires U_CHARSET_IS_UTF8 1 - -Signed-off-by: Tim Hughes ---- - source/common/unicode/platform.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/source/common/unicode/platform.h b/source/common/unicode/platform.h -index 1b2ab30..cca7039 100644 ---- a/source/common/unicode/platform.h -+++ b/source/common/unicode/platform.h -@@ -543,7 +543,7 @@ - #elif U_PLATFORM == U_PF_ANDROID || U_PLATFORM_IS_DARWIN_BASED - # define U_CHARSET_IS_UTF8 1 - #else --# define U_CHARSET_IS_UTF8 0 -+# define U_CHARSET_IS_UTF8 1 - #endif - - /** @} */ --- -1.9.0.msysgit.0 - diff --git a/windows/patches/icu/0003-Add-minimal-icu.sln.patch b/windows/patches/icu/0003-Add-minimal-icu.sln.patch deleted file mode 100644 index 62ce164d8..000000000 --- a/windows/patches/icu/0003-Add-minimal-icu.sln.patch +++ /dev/null @@ -1,71 +0,0 @@ -From dcb7b9172a3f7ec5d607696a86fefad69c03a400 Mon Sep 17 00:00:00 2001 -From: Tim Hughes -Date: Mon, 21 Apr 2014 13:33:59 +0100 -Subject: [PATCH 3/3] Add minimal icu.sln - -Signed-off-by: Tim Hughes ---- - source/allinone/icu.sln | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 51 insertions(+) - create mode 100644 source/allinone/icu.sln - -diff --git a/source/allinone/icu.sln b/source/allinone/icu.sln -new file mode 100644 -index 0000000..b09697f ---- /dev/null -+++ b/source/allinone/icu.sln -@@ -0,0 +1,51 @@ -+Microsoft Visual Studio Solution File, Format Version 12.00 -+# Visual Studio Express 2013 for Windows Desktop -+VisualStudioVersion = 12.0.21005.1 -+MinimumVisualStudioVersion = 10.0.40219.1 -+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "..\common\common.vcxproj", "{73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}" -+EndProject -+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "i18n", "..\i18n\i18n.vcxproj", "{0178B127-6269-407D-B112-93877BB62776}" -+EndProject -+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stubdata", "..\stubdata\stubdata.vcxproj", "{203EC78A-0531-43F0-A636-285439BDE025}" -+EndProject -+Global -+ GlobalSection(SolutionConfigurationPlatforms) = preSolution -+ Debug|Win32 = Debug|Win32 -+ Debug|x64 = Debug|x64 -+ Release|Win32 = Release|Win32 -+ Release|x64 = Release|x64 -+ EndGlobalSection -+ GlobalSection(ProjectConfigurationPlatforms) = postSolution -+ {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}.Debug|Win32.ActiveCfg = Debug|Win32 -+ {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}.Debug|Win32.Build.0 = Debug|Win32 -+ {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}.Debug|x64.ActiveCfg = Debug|x64 -+ {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}.Debug|x64.Build.0 = Debug|x64 -+ {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}.Release|Win32.ActiveCfg = Release|Win32 -+ {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}.Release|Win32.Build.0 = Release|Win32 -+ {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}.Release|x64.ActiveCfg = Release|x64 -+ {73C0A65B-D1F2-4DE1-B3A6-15DAD2C23F3D}.Release|x64.Build.0 = Release|x64 -+ {0178B127-6269-407D-B112-93877BB62776}.Debug|Win32.ActiveCfg = Debug|Win32 -+ {0178B127-6269-407D-B112-93877BB62776}.Debug|Win32.Build.0 = Debug|Win32 -+ {0178B127-6269-407D-B112-93877BB62776}.Debug|x64.ActiveCfg = Debug|x64 -+ {0178B127-6269-407D-B112-93877BB62776}.Debug|x64.Build.0 = Debug|x64 -+ {0178B127-6269-407D-B112-93877BB62776}.Release|Win32.ActiveCfg = Release|Win32 -+ {0178B127-6269-407D-B112-93877BB62776}.Release|Win32.Build.0 = Release|Win32 -+ {0178B127-6269-407D-B112-93877BB62776}.Release|x64.ActiveCfg = Release|x64 -+ {0178B127-6269-407D-B112-93877BB62776}.Release|x64.Build.0 = Release|x64 -+ {203EC78A-0531-43F0-A636-285439BDE025}.Debug|Win32.ActiveCfg = Debug|Win32 -+ {203EC78A-0531-43F0-A636-285439BDE025}.Debug|Win32.Build.0 = Debug|Win32 -+ {203EC78A-0531-43F0-A636-285439BDE025}.Debug|x64.ActiveCfg = Debug|x64 -+ {203EC78A-0531-43F0-A636-285439BDE025}.Debug|x64.Build.0 = Debug|x64 -+ {203EC78A-0531-43F0-A636-285439BDE025}.Release|Win32.ActiveCfg = Release|Win32 -+ {203EC78A-0531-43F0-A636-285439BDE025}.Release|Win32.Build.0 = Release|Win32 -+ {203EC78A-0531-43F0-A636-285439BDE025}.Release|x64.ActiveCfg = Release|x64 -+ {203EC78A-0531-43F0-A636-285439BDE025}.Release|x64.Build.0 = Release|x64 -+ EndGlobalSection -+ GlobalSection(SolutionProperties) = preSolution -+ HideSolutionNode = FALSE -+ EndGlobalSection -+ GlobalSection(SubversionScc) = preSolution -+ Svn-Managed = True -+ Manager = AnkhSVN - Subversion Support for Visual Studio -+ EndGlobalSection -+EndGlobal --- -1.9.0.msysgit.0 - diff --git a/windows/qt_plugin_import.cpp b/windows/qt_plugin_import.cpp deleted file mode 100644 index b3afd8a4e..000000000 --- a/windows/qt_plugin_import.cpp +++ /dev/null @@ -1,4 +0,0 @@ -// This file is autogenerated by qmake. It imports static plugin classes for -// static plugins specified using QTPLUGIN and QT_PLUGIN_CLASS. variables. -#include -Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin) diff --git a/windows/stdafx.cpp b/windows/stdafx.cpp deleted file mode 100644 index d3c5fc299..000000000 --- a/windows/stdafx.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - This file is part of cpp-ethereum. - - cpp-ethereum 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. - - cpp-ethereum 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 cpp-ethereum. If not, see . -*/ -/** @file stdafx.cpp - * @author Tim Hughes - * @date 2014 - */ - diff --git a/windows/stdafx.h b/windows/stdafx.h deleted file mode 100644 index 5a4e4d27d..000000000 --- a/windows/stdafx.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - This file is part of cpp-ethereum. - - cpp-ethereum 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. - - cpp-ethereum 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 cpp-ethereum. If not, see . -*/ -/** @file stdafx.h - * @author Tim Hughes - * @date 2014 - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#pragma warning(push) -#pragma warning(disable: 4100 4267) -#include -#pragma warning(pop) - - From c1948f05e1244d8465f2a9c608ca1a9f1a1f2f5e Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 9 Dec 2014 01:15:25 +0100 Subject: [PATCH 102/277] removed old unused precompiled headers for msvc --- libdevcore/_libdevcore.cpp | 13 ------------- libethcore/_libethcore.cpp | 7 ------- libevm/_libevm.cpp | 6 ------ libp2p/_libp2p.cpp | 9 --------- 4 files changed, 35 deletions(-) delete mode 100644 libdevcore/_libdevcore.cpp delete mode 100644 libethcore/_libethcore.cpp delete mode 100644 libevm/_libevm.cpp delete mode 100644 libp2p/_libp2p.cpp diff --git a/libdevcore/_libdevcore.cpp b/libdevcore/_libdevcore.cpp deleted file mode 100644 index 0605791de..000000000 --- a/libdevcore/_libdevcore.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#ifdef _MSC_VER -#include "All.h" -#include "Common.cpp" -#include "CommonData.cpp" -#include "CommonIO.cpp" -#include "CommonJS.h" -#include "FixedHash.cpp" -#include "Guards.cpp" -#include "Log.cpp" -#include "RangeMask.cpp" -#include "RLP.cpp" -#include "Worker.cpp" -#endif diff --git a/libethcore/_libethcore.cpp b/libethcore/_libethcore.cpp deleted file mode 100644 index 93eaf0d16..000000000 --- a/libethcore/_libethcore.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#ifdef _MSC_VER -#include "All.h" -#include "BlockInfo.cpp" -#include "CommonEth.cpp" -#include "ProofOfWork.cpp" -#include "Exceptions.cpp" -#endif diff --git a/libevm/_libevm.cpp b/libevm/_libevm.cpp deleted file mode 100644 index 27186cbf2..000000000 --- a/libevm/_libevm.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#ifdef _MSC_VER -#include "All.h" -#include "ExtVMFace.cpp" -#include "FeeStructure.cpp" -#include "VM.cpp" -#endif diff --git a/libp2p/_libp2p.cpp b/libp2p/_libp2p.cpp deleted file mode 100644 index 440ba362b..000000000 --- a/libp2p/_libp2p.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#ifdef _MSC_VER -#include "All.h" -#include "Capability.cpp" -#include "Common.cpp" -#include "Host.cpp" -#include "HostCapability.cpp" -#include "Session.cpp" -#include "UPnP.cpp" -#endif From 5f4627043da856068a82b482ba76c46e2a3c26f4 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 9 Dec 2014 09:39:46 +0100 Subject: [PATCH 103/277] - returning empty string instead of NULL --- libdevcore/CommonJS.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libdevcore/CommonJS.cpp b/libdevcore/CommonJS.cpp index 8d8638da5..9dc04b7e7 100644 --- a/libdevcore/CommonJS.cpp +++ b/libdevcore/CommonJS.cpp @@ -87,22 +87,22 @@ std::string fromRaw(h256 _n, unsigned* _inc) std::string s((char const*)_n.data(), 32); auto l = s.find_first_of('\0'); if (!l) - return NULL; + return ""; if (l != std::string::npos) { auto p = s.find_first_not_of('\0', l); if (!(p == std::string::npos || (_inc && p == 31))) - return NULL; + return ""; if (_inc) *_inc = (byte)s[31]; s.resize(l); } for (auto i: s) if (i < 32) - return NULL; + return ""; return s; } - return NULL; + return ""; } Address fromString(std::string _sn) From 44de002f3fc2c88f228e25cf09e87a7165c63a4b Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 9 Dec 2014 13:08:02 +0100 Subject: [PATCH 104/277] added curl libaries, which are required for testeth project --- cmake/EthDependencies.cmake | 6 ++++++ extdep/CMakeLists.txt | 1 + libp2p/Host.cpp | 2 +- test/CMakeLists.txt | 1 + 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index fb2aafd47..f957dd3ac 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -71,6 +71,12 @@ if (GMP_FOUND) message(" - gmp lib : ${GMP_LIBRARY}") endif() +# curl is only requried for tests +# TODO specify min curl version, on windows we are currenly using 7.29 +find_package (curl) +message(" - curl header: ${CURL_INCLUDE_DIR}") +message(" - curl lib : ${CURL_LIBRARY}") + # TODO make headless client optional find_package (QT5Core REQUIRED) find_package (QT5Gui REQUIRED) diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index cea32c80f..031093f56 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -44,6 +44,7 @@ else() eth_download(qt) eth_download(cryptopp) eth_download(boost) + eth_download(curl) endif() diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 93a6ce672..52ceb5df3 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -42,7 +42,7 @@ Host::Host(std::string const& _clientVersion, NetworkPreferences const& _n, bool m_clientVersion(_clientVersion), m_netPrefs(_n), m_ifAddresses(Network::getInterfaceAddresses()), - m_ioService(2), + m_ioService(), m_acceptorV4(m_ioService), m_key(KeyPair::create()) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e27e0949d..3beb36643 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -18,6 +18,7 @@ target_link_libraries(testeth secp256k1) target_link_libraries(testeth solidity) target_link_libraries(testeth webthree) target_link_libraries(testeth ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE}) +target_link_libraries(testeth ${CURL_LIBRARY}) if (JSON_RPC_CPP_FOUND) target_link_libraries(testeth web3jsonrpc) From 546ff5c4f692d4e3ecdeb51223ca21963b95f5d1 Mon Sep 17 00:00:00 2001 From: debris Date: Tue, 9 Dec 2014 16:19:17 +0100 Subject: [PATCH 105/277] ubuntu cmake fixes --- cmake/EthDependencies.cmake | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index f957dd3ac..de1407b0a 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -5,7 +5,7 @@ # this must be set to point to the same directory as $ETH_DEPENDENCY_INSTALL_DIR in /extdep directory string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name) set (CMAKE_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install/${_system_name}") -set (CMAKE_PREFIX_PATH ${CMAKE_DEPENDENCY_INSTALL_DIR}) +set (CMAKE_PREFIX_PATH ${CMAKE_DEPENDENCY_INSTALL_DIR} ";/usr") # Qt5 requires opengl # TODO use proper version of windows SDK (32 vs 64) @@ -73,13 +73,13 @@ endif() # curl is only requried for tests # TODO specify min curl version, on windows we are currenly using 7.29 -find_package (curl) +find_package (CURL) message(" - curl header: ${CURL_INCLUDE_DIR}") message(" - curl lib : ${CURL_LIBRARY}") # TODO make headless client optional -find_package (QT5Core REQUIRED) -find_package (QT5Gui REQUIRED) +find_package (Qt5Core REQUIRED) +find_package (Qt5Gui REQUIRED) find_package (Qt5Quick REQUIRED) find_package (Qt5Qml REQUIRED) find_package (Qt5Network REQUIRED) @@ -87,16 +87,20 @@ find_package (Qt5Widgets REQUIRED) find_package (Qt5WebKit REQUIRED) find_package (Qt5WebKitWidgets REQUIRED) -# we have to specify here if we want static and boost version, that is really important -set(Boost_USE_STATIC_LIBS ON) -set(Boost_USE_MULTITHREADED ON) - -# TODO hanlde other msvc versions or it will fail find them if (${CMAKE_CXX_COMPILER_ID} MATCHES "MSVC") + # TODO hanlde other msvc versions or it will fail find them set(Boost_COMPILER -vc120) + set(Boost_USE_STATIC_LIBS ON) + set(Boost_USE_MULTITHREADED ON) +elseif(APPLE) + set(Boost_USE_STATIC_LIBS ON) + set(Boost_USE_MULTITHREADED ON) +elseif(UNIX) + set(Boost_USE_STATIC_LIBS OFF) + set(Boost_USE_MULTITHREADED ON) endif() -find_package(Boost 1.55.0 REQUIRED COMPONENTS thread date_time system regex chrono filesystem unit_test_framework) +find_package(Boost 1.54.0 REQUIRED COMPONENTS thread date_time system regex chrono filesystem unit_test_framework) message(" - boost header: ${Boost_INCLUDE_DIRS}") message(" - boost lib : ${Boost_LIBRARIES}") From c9e413daafaaab668918bfd24182eea6944d8a9c Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 9 Dec 2014 16:54:05 +0100 Subject: [PATCH 106/277] empty sha test && common fix on mac --- cmake/EthDependencies.cmake | 2 +- test/genesis.cpp | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index de1407b0a..600d9b72e 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -5,7 +5,7 @@ # this must be set to point to the same directory as $ETH_DEPENDENCY_INSTALL_DIR in /extdep directory string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name) set (CMAKE_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install/${_system_name}") -set (CMAKE_PREFIX_PATH ${CMAKE_DEPENDENCY_INSTALL_DIR} ";/usr") +set (CMAKE_PREFIX_PATH ${CMAKE_DEPENDENCY_INSTALL_DIR}) # Qt5 requires opengl # TODO use proper version of windows SDK (32 vs 64) diff --git a/test/genesis.cpp b/test/genesis.cpp index 6839d42e2..90974d1b8 100644 --- a/test/genesis.cpp +++ b/test/genesis.cpp @@ -36,6 +36,15 @@ namespace js = json_spirit; BOOST_AUTO_TEST_SUITE(BasicTests) +BOOST_AUTO_TEST_CASE(emptySHA3Types) +{ + h256 emptyListSHA3(fromHex("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")); + BOOST_REQUIRE_EQUAL(emptyListSHA3, EmptyListSHA3); + + h256 emptySHA3(fromHex("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")); + BOOST_REQUIRE_EQUAL(emptySHA3, EmptySHA3); +} + BOOST_AUTO_TEST_CASE(genesis_tests) { string testPath = test::getTestPath(); From ea8d11378c29003745b240bf2f4598a3885228a1 Mon Sep 17 00:00:00 2001 From: ethdev Date: Tue, 9 Dec 2014 17:05:12 +0100 Subject: [PATCH 107/277] small windows fix --- cmake/EthDependencies.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 600d9b72e..7c0fe048c 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -87,7 +87,7 @@ find_package (Qt5Widgets REQUIRED) find_package (Qt5WebKit REQUIRED) find_package (Qt5WebKitWidgets REQUIRED) -if (${CMAKE_CXX_COMPILER_ID} MATCHES "MSVC") +if (WIN32) # TODO hanlde other msvc versions or it will fail find them set(Boost_COMPILER -vc120) set(Boost_USE_STATIC_LIBS ON) From 7418077b4c7577b4462696a9d6f3bd922ec93e51 Mon Sep 17 00:00:00 2001 From: subtly Date: Tue, 9 Dec 2014 18:52:04 +0100 Subject: [PATCH 108/277] fix for windows compliation (circular dependency between statics initialized dynamically and dynamically initialized statics) --- libdevcrypto/SHA3.cpp | 2 +- test/crypto.cpp | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/libdevcrypto/SHA3.cpp b/libdevcrypto/SHA3.cpp index 1fc9be950..b7a47b745 100644 --- a/libdevcrypto/SHA3.cpp +++ b/libdevcrypto/SHA3.cpp @@ -30,7 +30,7 @@ namespace dev { h256 EmptySHA3 = sha3(bytesConstRef()); -h256 EmptyListSHA3 = sha3(RLPEmptyList); +h256 EmptyListSHA3 = sha3(rlpList()); std::string sha3(std::string const& _input, bool _hex) { diff --git a/test/crypto.cpp b/test/crypto.cpp index 466015ad7..291893f59 100644 --- a/test/crypto.cpp +++ b/test/crypto.cpp @@ -44,6 +44,15 @@ static CryptoPP::OID s_curveOID(CryptoPP::ASN1::secp256k1()); static CryptoPP::DL_GroupParameters_EC s_params(s_curveOID); static CryptoPP::DL_GroupParameters_EC::EllipticCurve s_curve(s_params.GetCurve()); +BOOST_AUTO_TEST_CASE(emptySHA3Types) +{ + h256 emptyListSHA3(fromHex("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")); + BOOST_REQUIRE_EQUAL(emptyListSHA3, EmptyListSHA3); + + h256 emptySHA3(fromHex("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")); + BOOST_REQUIRE_EQUAL(emptySHA3, EmptySHA3); +} + BOOST_AUTO_TEST_CASE(cryptopp_patch) { KeyPair k = KeyPair::create(); From 391512d0a25a68ba2cf56deac5f8e826b8ff5d33 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 9 Dec 2014 19:48:03 +0100 Subject: [PATCH 109/277] fixed compiler settings on windows, added few comments --- cmake/EthCompilerSettings.cmake | 16 +++++++++------- cmake/EthDependencies.cmake | 23 +++++++++++++++++------ 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index d821067a8..677467bea 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -4,7 +4,12 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB -fPIC") + set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DETH_DEBUG") + set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE") + set(CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG -DETH_RELEASE") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_DEBUG") set(ETH_SHARED 1) + execute_process( COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) if (NOT (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7)) @@ -14,6 +19,10 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB -fPIC") + set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DETH_DEBUG") + set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE") + set(CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG -DETH_RELEASE") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_DEBUG") set(ETH_SHARED 1) elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") @@ -28,10 +37,3 @@ else () message(FATAL_ERROR "Your C++ compiler does not support C++11. You have ${CMAKE_CXX_COMPILER_ID}") endif () -# Initialize CXXFLAGS -# CMAKE_CXX_FLAGS was set before -set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DETH_DEBUG") -set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE") -set(CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG -DETH_RELEASE") -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_DEBUG") - diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 7c0fe048c..f55a93d38 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -77,6 +77,8 @@ find_package (CURL) message(" - curl header: ${CURL_INCLUDE_DIR}") message(" - curl lib : ${CURL_LIBRARY}") +# find all of the Qt packages +# remember to use 'Qt' instead of 'QT', cause unix is case sensitive # TODO make headless client optional find_package (Qt5Core REQUIRED) find_package (Qt5Gui REQUIRED) @@ -87,17 +89,26 @@ find_package (Qt5Widgets REQUIRED) find_package (Qt5WebKit REQUIRED) find_package (Qt5WebKitWidgets REQUIRED) -if (WIN32) +# use multithreaded boost libraries, with -mt suffix +set(Boost_USE_MULTITHREADED ON) + +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + # TODO hanlde other msvc versions or it will fail find them set(Boost_COMPILER -vc120) + # use static boost libraries *.lib set(Boost_USE_STATIC_LIBS ON) - set(Boost_USE_MULTITHREADED ON) -elseif(APPLE) + +elseif (APPLE) + + # use static boost libraries *.a set(Boost_USE_STATIC_LIBS ON) - set(Boost_USE_MULTITHREADED ON) -elseif(UNIX) + +elseif (UNIX) + + # use dynamic boost libraries .dll set(Boost_USE_STATIC_LIBS OFF) - set(Boost_USE_MULTITHREADED ON) + endif() find_package(Boost 1.54.0 REQUIRED COMPONENTS thread date_time system regex chrono filesystem unit_test_framework) From 281a9e2b226280b212fe72c241b0cf5a9930d5a8 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 10 Dec 2014 11:39:41 +0100 Subject: [PATCH 110/277] jsonrpc option in cmakes, removed all warnings --- CMakeLists.txt | 54 ++++++++++++++----------- alethzero/CMakeLists.txt | 11 ++++-- cmake/EthDependencies.cmake | 46 ++++++++++++++-------- libdevcore/CMakeLists.txt | 7 ++++ libdevcrypto/CMakeLists.txt | 6 +++ libethcore/CMakeLists.txt | 6 +++ libethereum/CMakeLists.txt | 8 +++- libevm/CMakeLists.txt | 6 +++ libevmcore/CMakeLists.txt | 6 +++ libjsqrc/CMakeLists.txt | 5 +++ liblll/CMakeLists.txt | 6 +++ libp2p/CMakeLists.txt | 6 +++ libqethereum/CMakeLists.txt | 9 ++++- libserpent/CMakeLists.txt | 6 +++ libsolidity/CMakeLists.txt | 6 +++ libweb3jsonrpc/CMakeLists.txt | 8 +++- libwebthree/CMakeLists.txt | 8 +++- libwhisper/CMakeLists.txt | 10 ++++- mix/CMakeLists.txt | 11 ++++-- secp256k1/CMakeLists.txt | 6 +++ third/CMakeLists.txt | 74 +++++++++++++++-------------------- 21 files changed, 212 insertions(+), 93 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d070ccc1e..3aad38f71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,7 @@ function(createDefaultCacheConfig) set(LANGUAGES OFF CACHE BOOL "Limit build to Serpent/LLL tools") set(VMTRACE OFF CACHE BOOL "VM tracing and run-time checks (useful for cross-implementation VM debugging)") set(PARANOIA OFF CACHE BOOL "Additional run-time checks") + set(JSONRPC ON CACHE BOOL "Build with jsonprc. default on") endfunction() @@ -85,7 +86,7 @@ cmake_policy(SET CMP0015 NEW) createDefaultCacheConfig() configureProject() -message("-- LANGUAGES: ${LANGUAGES}; VMTRACE: ${VMTRACE}; PARANOIA: ${PARANOIA}; HEADLESS: ${HEADLESS}") +message("-- LANGUAGES: ${LANGUAGES}; VMTRACE: ${VMTRACE}; PARANOIA: ${PARANOIA}; HEADLESS: ${HEADLESS}; JSONRPC: ${JSONRPC}") # Default TARGET_PLATFORM to "linux". @@ -107,23 +108,27 @@ include(EthDependencies) createBuildInfo() -add_subdirectory(libdevcore) -add_subdirectory(libevmcore) -add_subdirectory(liblll) -add_subdirectory(libserpent) -add_subdirectory(libsolidity) +# TODO discuss that during PR. are we still using that? + if(NOT APPLE) if(PYTHON_LS) add_subdirectory(libpyserpent) endif() endif() +add_subdirectory(libdevcore) +add_subdirectory(libevmcore) +add_subdirectory(liblll) +add_subdirectory(libserpent) +add_subdirectory(libsolidity) add_subdirectory(lllc) add_subdirectory(solc) add_subdirectory(sc) -if (JSON_RPC_CPP_FOUND) + +if (JSONRPC) add_subdirectory(libweb3jsonrpc) endif() + if (NOT LANGUAGES) add_subdirectory(secp256k1) add_subdirectory(libp2p) @@ -133,6 +138,8 @@ if (NOT LANGUAGES) add_subdirectory(libethcore) add_subdirectory(libevm) add_subdirectory(libethereum) + +# TODO is this 'TODO remove' still valid? # add_subdirectory(libethereumx) # TODO remove add_subdirectory(libwebthree) @@ -141,38 +148,39 @@ if (NOT LANGUAGES) if("x${CMAKE_BUILD_TYPE}" STREQUAL "xDebug") add_subdirectory(exp) endif () + + # TODO check msvc if(NOT ("${TARGET_PLATFORM}" STREQUAL "w64")) add_subdirectory(neth) endif () - if(QTQML) - add_definitions(-DETH_QTQML) - endif() - if(NOT HEADLESS) + # TODO discuss that during PR. are we still using that? + #if(QTQML) + #add_definitions(-DETH_QTQML) + #endif() + + if (NOT HEADLESS) + + # TODO move that somewhere else! if ("${TARGET_PLATFORM}" STREQUAL "w64") cmake_policy(SET CMP0020 NEW) endif () - if (NOT JSON_RPC_CPP_FOUND) - message(FATAL_ERROR "Alethzero requires jsonrpc.") - endif() - + add_subdirectory(libjsqrc) add_subdirectory(libqethereum) - if (NOT JSON_RPC_CPP_FOUND) - message (FATAL_ERROR "AlethZero requires json-rpc-cpp!") - else() - add_subdirectory(alethzero) - endif() + add_subdirectory(alethzero) add_subdirectory(third) add_subdirectory(mix) - if(QTQML) + + # TODO discuss that during PR. are we still using that? + #if(QTQML) #add_subdirectory(iethxi) #add_subdirectory(walleth) // resurect once we want to submit ourselves to QML. - endif() + #endif() + endif() endif() - enable_testing() add_test(NAME alltests WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/test COMMAND testeth) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index 07500390b..47d1f73e8 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -1,4 +1,9 @@ -cmake_policy(SET CMP0015 OLD) +cmake_policy(SET CMP0015 NEW) +# this policy was introduced in cmake 3.0 +# remove if, once 3.0 will be used on unix +if (APPLE) + cmake_policy(SET CMP0043 OLD) +endif() set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) @@ -36,7 +41,7 @@ endif () add_dependencies(${EXECUTABLE} BuildInfo.h) -qt5_use_modules(${EXECUTABLE} Core) +target_link_libraries(${EXECUTABLE} Qt5::Core) target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES}) target_link_libraries(${EXECUTABLE} webthree) target_link_libraries(${EXECUTABLE} qethereum) @@ -57,7 +62,7 @@ if (APPLE) # First have qt5 install plugins and frameworks # replace CMAKE_PREFIX_PATH with QT_PATH ? add_custom_command(TARGET ${EXECUTABLE} POST_BUILD - COMMAND ${CMAKE_PREFIX_PATH}/bin/macdeployqt ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app + COMMAND ${CMAKE_DEPENDENCY_INSTALL_DIR}/bin/macdeployqt ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) # This tool and next will inspect linked libraries in order to determine which dependencies are required diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index f55a93d38..4877b06d5 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -36,12 +36,17 @@ message(" - Jsoncpp lib : ${JSONCPP_LIBRARIES}") # json-rpc-cpp support is currently not mandatory # TODO make headless client optional # TODO get rid of -DETH_JSONRPC -find_package (JsonRpcCpp 0.3.2) -if (JSON_RPC_CPP_FOUND) +if (JSONRPC) + + find_package (JsonRpcCpp 0.3.2) + if (NOT JSON_RPC_CPP_FOUND) + message (FATAL_ERROR "JSONRPC 0.3.2. not found") + endif() message (" - json-rpc-cpp header: ${JSON_RPC_CPP_INCLUDE_DIRS}") message (" - json-rpc-cpp lib : ${JSON_RPC_CPP_LIBRARIES}") add_definitions(-DETH_JSONRPC) -endif() + +endif() #JSONRPC # TODO readline package does not yet check for correct version number # TODO make readline package dependent on cmake options @@ -77,36 +82,45 @@ find_package (CURL) message(" - curl header: ${CURL_INCLUDE_DIR}") message(" - curl lib : ${CURL_LIBRARY}") +# do not compile GUI +if (NOT HEADLESS) + +# we need json rpc to build alethzero + if (NOT JSON_RPC_CPP_FOUND) + message (FATAL_ERROR "JSONRPC is required for GUI client") + endif() + # find all of the Qt packages # remember to use 'Qt' instead of 'QT', cause unix is case sensitive # TODO make headless client optional -find_package (Qt5Core REQUIRED) -find_package (Qt5Gui REQUIRED) -find_package (Qt5Quick REQUIRED) -find_package (Qt5Qml REQUIRED) -find_package (Qt5Network REQUIRED) -find_package (Qt5Widgets REQUIRED) -find_package (Qt5WebKit REQUIRED) -find_package (Qt5WebKitWidgets REQUIRED) + find_package (Qt5Core REQUIRED) + find_package (Qt5Gui REQUIRED) + find_package (Qt5Quick REQUIRED) + find_package (Qt5Qml REQUIRED) + find_package (Qt5Network REQUIRED) + find_package (Qt5Widgets REQUIRED) + find_package (Qt5WebKit REQUIRED) + find_package (Qt5WebKitWidgets REQUIRED) + +endif() #HEADLESS # use multithreaded boost libraries, with -mt suffix set(Boost_USE_MULTITHREADED ON) if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") - # TODO hanlde other msvc versions or it will fail find them +# TODO hanlde other msvc versions or it will fail find them set(Boost_COMPILER -vc120) - # use static boost libraries *.lib +# use static boost libraries *.lib set(Boost_USE_STATIC_LIBS ON) elseif (APPLE) - # use static boost libraries *.a +# use static boost libraries *.a set(Boost_USE_STATIC_LIBS ON) elseif (UNIX) - - # use dynamic boost libraries .dll +# use dynamic boost libraries .dll set(Boost_USE_STATIC_LIBS OFF) endif() diff --git a/libdevcore/CMakeLists.txt b/libdevcore/CMakeLists.txt index 06cbe850c..b1a21470f 100644 --- a/libdevcore/CMakeLists.txt +++ b/libdevcore/CMakeLists.txt @@ -1,4 +1,11 @@ cmake_policy(SET CMP0015 OLD) +# this policy was introduced in cmake 3.0 +# remove if, once 3.0 will be used on unix +if (APPLE) + # old policy do not use MACOSX_RPATH + cmake_policy(SET CMP0042 OLD) +endif() + set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") diff --git a/libdevcrypto/CMakeLists.txt b/libdevcrypto/CMakeLists.txt index d2db758af..059cae7f9 100644 --- a/libdevcrypto/CMakeLists.txt +++ b/libdevcrypto/CMakeLists.txt @@ -1,4 +1,10 @@ cmake_policy(SET CMP0015 OLD) +# this policy was introduced in cmake 3.0 +# remove if, once 3.0 will be used on unix +if (APPLE) + # old policy do not use MACOSX_RPATH + cmake_policy(SET CMP0042 OLD) +endif() set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) diff --git a/libethcore/CMakeLists.txt b/libethcore/CMakeLists.txt index 869b6092b..b2e90a622 100644 --- a/libethcore/CMakeLists.txt +++ b/libethcore/CMakeLists.txt @@ -1,4 +1,10 @@ cmake_policy(SET CMP0015 NEW) +# this policy was introduced in cmake 3.0 +# remove if, once 3.0 will be used on unix +if (APPLE) + # old policy do not use MACOSX_RPATH + cmake_policy(SET CMP0042 OLD) +endif() set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) diff --git a/libethereum/CMakeLists.txt b/libethereum/CMakeLists.txt index ac5bd7136..40c53a8a5 100644 --- a/libethereum/CMakeLists.txt +++ b/libethereum/CMakeLists.txt @@ -1,4 +1,10 @@ -cmake_policy(SET CMP0015 OLD) +cmake_policy(SET CMP0015 NEW) +# this policy was introduced in cmake 3.0 +# remove if, once 3.0 will be used on unix +if (APPLE) + # old policy do not use MACOSX_RPATH + cmake_policy(SET CMP0042 OLD) +endif() set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") diff --git a/libevm/CMakeLists.txt b/libevm/CMakeLists.txt index 717904912..a4a8c4f3c 100644 --- a/libevm/CMakeLists.txt +++ b/libevm/CMakeLists.txt @@ -1,4 +1,10 @@ cmake_policy(SET CMP0015 NEW) +# this policy was introduced in cmake 3.0 +# remove if, once 3.0 will be used on unix +if (APPLE) + # old policy do not use MACOSX_RPATH + cmake_policy(SET CMP0042 OLD) +endif() set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") diff --git a/libevmcore/CMakeLists.txt b/libevmcore/CMakeLists.txt index 0f71dcd40..737df945b 100644 --- a/libevmcore/CMakeLists.txt +++ b/libevmcore/CMakeLists.txt @@ -1,4 +1,10 @@ cmake_policy(SET CMP0015 NEW) +# this policy was introduced in cmake 3.0 +# remove if, once 3.0 will be used on unix +if (APPLE) + # old policy do not use MACOSX_RPATH + cmake_policy(SET CMP0042 OLD) +endif() set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") diff --git a/libjsqrc/CMakeLists.txt b/libjsqrc/CMakeLists.txt index b8beec2ff..9533ddd1a 100644 --- a/libjsqrc/CMakeLists.txt +++ b/libjsqrc/CMakeLists.txt @@ -1,4 +1,9 @@ cmake_policy(SET CMP0015 NEW) +# this policy was introduced in cmake 3.0 +# remove if, once 3.0 will be used on unix +if (APPLE) + cmake_policy(SET CMP0043 OLD) +endif() set(CMAKE_AUTOMOC OFF) qt5_add_resources(JSQRC js.qrc) diff --git a/liblll/CMakeLists.txt b/liblll/CMakeLists.txt index e2c000010..908b8caf3 100644 --- a/liblll/CMakeLists.txt +++ b/liblll/CMakeLists.txt @@ -1,4 +1,10 @@ cmake_policy(SET CMP0015 NEW) +# this policy was introduced in cmake 3.0 +# remove if, once 3.0 will be used on unix +if (APPLE) + # old policy do not use MACOSX_RPATH + cmake_policy(SET CMP0042 OLD) +endif() set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") diff --git a/libp2p/CMakeLists.txt b/libp2p/CMakeLists.txt index e354a1c65..5ace09dda 100644 --- a/libp2p/CMakeLists.txt +++ b/libp2p/CMakeLists.txt @@ -1,4 +1,10 @@ cmake_policy(SET CMP0015 NEW) +# this policy was introduced in cmake 3.0 +# remove if, once 3.0 will be used on unix +if (APPLE) + # old policy do not use MACOSX_RPATH + cmake_policy(SET CMP0042 OLD) +endif() set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") diff --git a/libqethereum/CMakeLists.txt b/libqethereum/CMakeLists.txt index 56e0ba94a..9bc8c5de8 100644 --- a/libqethereum/CMakeLists.txt +++ b/libqethereum/CMakeLists.txt @@ -1,4 +1,11 @@ -cmake_policy(SET CMP0015 OLD) +cmake_policy(SET CMP0015 NEW) +# this policy was introduced in cmake 3.0 +# remove if, once 3.0 will be used on unix +if (APPLE) + # old policy do not use MACOSX_RPATH + cmake_policy(SET CMP0042 OLD) + cmake_policy(SET CMP0043 OLD) +endif() set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) diff --git a/libserpent/CMakeLists.txt b/libserpent/CMakeLists.txt index 365b1bc9e..4d4a25e58 100644 --- a/libserpent/CMakeLists.txt +++ b/libserpent/CMakeLists.txt @@ -1,4 +1,10 @@ cmake_policy(SET CMP0015 NEW) +# this policy was introduced in cmake 3.0 +# remove if, once 3.0 will be used on unix +if (APPLE) + # old policy do not use MACOSX_RPATH + cmake_policy(SET CMP0042 OLD) +endif() set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index 895b22ae0..ad93609f0 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -1,4 +1,10 @@ cmake_policy(SET CMP0015 NEW) +# this policy was introduced in cmake 3.0 +# remove if, once 3.0 will be used on unix +if (APPLE) + # old policy do not use MACOSX_RPATH + cmake_policy(SET CMP0042 OLD) +endif() set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") diff --git a/libweb3jsonrpc/CMakeLists.txt b/libweb3jsonrpc/CMakeLists.txt index 133471d18..5ddbc186f 100644 --- a/libweb3jsonrpc/CMakeLists.txt +++ b/libweb3jsonrpc/CMakeLists.txt @@ -1,4 +1,10 @@ -cmake_policy(SET CMP0015 OLD) +cmake_policy(SET CMP0015 NEW) +# this policy was introduced in cmake 3.0 +# remove if, once 3.0 will be used on unix +if (APPLE) + # old policy do not use MACOSX_RPATH + cmake_policy(SET CMP0042 OLD) +endif() set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) diff --git a/libwebthree/CMakeLists.txt b/libwebthree/CMakeLists.txt index 09fe7f736..661786d1a 100644 --- a/libwebthree/CMakeLists.txt +++ b/libwebthree/CMakeLists.txt @@ -1,4 +1,10 @@ -cmake_policy(SET CMP0015 OLD) +cmake_policy(SET CMP0015 NEW) +# this policy was introduced in cmake 3.0 +# remove if, once 3.0 will be used on unix +if (APPLE) + # old policy do not use MACOSX_RPATH + cmake_policy(SET CMP0042 OLD) +endif() set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") diff --git a/libwhisper/CMakeLists.txt b/libwhisper/CMakeLists.txt index 3ab2f6097..89650db88 100644 --- a/libwhisper/CMakeLists.txt +++ b/libwhisper/CMakeLists.txt @@ -1,4 +1,10 @@ -cmake_policy(SET CMP0015 OLD) +cmake_policy(SET CMP0015 NEW) +# this policy was introduced in cmake 3.0 +# remove if, once 3.0 will be used on unix +if (APPLE) + # old policy do not use MACOSX_RPATH + cmake_policy(SET CMP0042 OLD) +endif() set(CMAKE_AUTOMOC OFF) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") @@ -30,4 +36,4 @@ target_link_libraries(${EXECUTABLE} p2p) target_link_libraries(${EXECUTABLE} secp256k1) install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) -install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) \ No newline at end of file +install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/mix/CMakeLists.txt b/mix/CMakeLists.txt index bdb682a09..03e8b45ff 100644 --- a/mix/CMakeLists.txt +++ b/mix/CMakeLists.txt @@ -1,9 +1,14 @@ +cmake_policy(SET CMP0015 NEW) +# this policy was introduced in cmake 3.0 +# remove if, once 3.0 will be used on unix +if (APPLE) + cmake_policy(SET CMP0043 OLD) +endif() + set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) include_directories(..) -#qt5_wrap_ui(ui_Main.h Main.ui) - qt5_add_resources(UI_RESOURCES qml.qrc) # Set name of binary and add_executable() @@ -54,7 +59,7 @@ target_link_libraries(${EXECUTEABLE} jsqrc) if (APPLE) # First have qt5 install plugins and frameworks add_custom_command(TARGET ${EXECUTEABLE} POST_BUILD - COMMAND /usr/local/opt/qt5/bin/macdeployqt -qmldir=${CMAKE_CURRENT_SOURCE_DIR}/qml ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTEABLE}.app + COMMAND ${CMAKE_DEPENDENCY_INSTALL_DIR}/bin/macdeployqt -qmldir=${CMAKE_CURRENT_SOURCE_DIR}/qml ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTEABLE}.app WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) # This tool and next will inspect linked libraries in order to determine which dependencies are required diff --git a/secp256k1/CMakeLists.txt b/secp256k1/CMakeLists.txt index 230bf76b9..beeee598f 100644 --- a/secp256k1/CMakeLists.txt +++ b/secp256k1/CMakeLists.txt @@ -1,4 +1,10 @@ cmake_policy(SET CMP0015 NEW) +# this policy was introduced in cmake 3.0 +# remove if, once 3.0 will be used on unix +if (APPLE) + # old policy do not use MACOSX_RPATH + cmake_policy(SET CMP0042 OLD) +endif() set(CMAKE_AUTOMOC OFF) set(CMAKE_ASM_COMPILER "yasm") diff --git a/third/CMakeLists.txt b/third/CMakeLists.txt index 383985318..de0581067 100644 --- a/third/CMakeLists.txt +++ b/third/CMakeLists.txt @@ -1,26 +1,21 @@ +cmake_policy(SET CMP0015 NEW) +# this policy was introduced in cmake 3.0 +# remove if, once 3.0 will be used on unix +if (APPLE) + cmake_policy(SET CMP0043 OLD) +endif() + set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) include_directories(..) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) -if (APPLE) - # Add homebrew path for qt5 - #set(CMAKE_PREFIX_PATH /usr/local/opt/qt5) - #include_directories(/usr/local/opt/qt5/include /usr/local/include) -elseif ("${TARGET_PLATFORM}" STREQUAL "w64") - set(SRC_LIST ${SRC_LIST} ../windows/qt_plugin_import.cpp) - include_directories(/usr/x86_64-w64-mingw32/include /usr/x86_64-w64-mingw32/include/QtCore /usr/x86_64-w64-mingw32/include/QtGui /usr/x86_64-w64-mingw32/include/QtQuick /usr/x86_64-w64-mingw32/include/QtQml /usr/x86_64-w64-mingw32/include/QtNetwork /usr/x86_64-w64-mingw32/include/QtWidgets /usr/x86_64-w64-mingw32/include/QtWebKit /usr/x86_64-w64-mingw32/include/QtWebKitWidgets) -elseif (UNIX) - set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ";$ENV{QTDIR}/lib/cmake") -endif () - - qt5_wrap_ui(ui_Main.h Main.ui) # Set name of binary and add_executable() file(GLOB HEADERS "*.h") if (APPLE) - set(EXECUTEABLE Third) + set(EXECUTABLE Third) set(BIN_INSTALL_DIR ".") set(DOC_INSTALL_DIR ".") @@ -31,34 +26,45 @@ if (APPLE) set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}") set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}") set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}") - set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTEABLE}) + set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTABLE}) set(MACOSX_BUNDLE_ICON_FILE third) include(BundleUtilities) - add_executable(${EXECUTEABLE} MACOSX_BUNDLE third.icns Main.ui ${SRC_LIST} ${HEADERS}) - set_target_properties(${EXECUTEABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") - SET_SOURCE_FILES_PROPERTIES(${EXECUTEABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) + add_executable(${EXECUTABLE} MACOSX_BUNDLE third.icns Main.ui ${SRC_LIST} ${HEADERS}) + set_target_properties(${EXECUTABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") + SET_SOURCE_FILES_PROPERTIES(${EXECUTABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) SET_SOURCE_FILES_PROPERTIES(${MACOSX_BUNDLE_ICON_FILE}.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") else () - set(EXECUTEABLE third) - add_executable(${EXECUTEABLE} Main.ui ${SRC_LIST} ${HEADERS}) + set(EXECUTABLE third) + add_executable(${EXECUTABLE} Main.ui ${SRC_LIST} ${HEADERS}) endif () -qt5_use_modules(${EXECUTEABLE} Core)# Gui Widgets Network WebKit WebKitWidgets) -target_link_libraries(${EXECUTEABLE} webthree qethereum ethereum evm ethcore secp256k1 gmp serpent lll evmcore devcore web3jsonrpc jsqrc) +target_link_libraries(${EXECUTABLE} Qt5::Core) +target_link_libraries(${EXECUTABLE} webthree) +target_link_libraries(${EXECUTABLE} qethereum) +target_link_libraries(${EXECUTABLE} ethereum) +target_link_libraries(${EXECUTABLE} evm) +target_link_libraries(${EXECUTABLE} ethcore) +target_link_libraries(${EXECUTABLE} secp256k1) +target_link_libraries(${EXECUTABLE} serpent) +target_link_libraries(${EXECUTABLE} lll) +target_link_libraries(${EXECUTABLE} evmcore) +target_link_libraries(${EXECUTABLE} devcore) +target_link_libraries(${EXECUTABLE} web3jsonrpc) +target_link_libraries(${EXECUTABLE} jsqrc) if (APPLE) # First have qt5 install plugins and frameworks - add_custom_command(TARGET ${EXECUTEABLE} POST_BUILD - COMMAND ${CMAKE_PREFIX_PATH}/bin/macdeployqt ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTEABLE}.app + add_custom_command(TARGET ${EXECUTABLE} POST_BUILD + COMMAND ${CMAKE_DEPENDENCY_INSTALL_DIR}/bin/macdeployqt ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) # This tool and next will inspect linked libraries in order to determine which dependencies are required if (${CMAKE_CFG_INTDIR} STREQUAL ".") - set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTEABLE}.app") + set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE}.app") else () - set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/\$ENV{CONFIGURATION}/${EXECUTEABLE}.app") + set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/\$ENV{CONFIGURATION}/${EXECUTABLE}.app") endif () install(CODE " include(BundleUtilities) @@ -72,23 +78,7 @@ if (APPLE) file(REMOVE \${LINGER_RM}) endif () ") -elseif ("${TARGET_PLATFORM}" STREQUAL "w64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-keep-inline-dllexport -static-libgcc -static-libstdc++ -static") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-s -Wl,-subsystem,windows -mthreads -L/usr/x86_64-w64-mingw32/plugins/platforms") - target_link_libraries(${EXECUTEABLE} gcc) - target_link_libraries(${EXECUTEABLE} mingw32 qtmain mswsock iphlpapi qwindows shlwapi Qt5PlatformSupport opengl32 gdi32 comdlg32 oleaut32 imm32 winmm ole32 uuid ws2_32) - target_link_libraries(${EXECUTEABLE} boost_system-mt-s) - target_link_libraries(${EXECUTEABLE} boost_filesystem-mt-s) - target_link_libraries(${EXECUTEABLE} boost_thread_win32-mt-s) - target_link_libraries(${EXECUTEABLE} crypt32) - target_link_libraries(${EXECUTEABLE} Qt5PlatformSupport) - set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) -elseif (UNIX) else () - target_link_libraries(${EXECUTEABLE} boost_system) - target_link_libraries(${EXECUTEABLE} boost_filesystem) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTEABLE} ${CMAKE_THREAD_LIBS_INIT}) - install( TARGETS ${EXECUTEABLE} RUNTIME DESTINATION bin ) + install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin) endif () From 7c26fa0afe2d2ff1d1498ec1df4262d2b46ef888 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 10 Dec 2014 11:52:08 +0100 Subject: [PATCH 111/277] common changes in cmakes --- mix/CMakeLists.txt | 57 ++++++++++++++++++++++---------------------- neth/CMakeLists.txt | 43 +++++++++------------------------ third/CMakeLists.txt | 2 ++ 3 files changed, 42 insertions(+), 60 deletions(-) diff --git a/mix/CMakeLists.txt b/mix/CMakeLists.txt index 03e8b45ff..3980f5642 100644 --- a/mix/CMakeLists.txt +++ b/mix/CMakeLists.txt @@ -14,7 +14,7 @@ qt5_add_resources(UI_RESOURCES qml.qrc) # Set name of binary and add_executable() file(GLOB HEADERS "*.h") if (APPLE) - set(EXECUTEABLE mix) + set(EXECUTABLE mix) set(BIN_INSTALL_DIR ".") set(DOC_INSTALL_DIR ".") @@ -25,48 +25,48 @@ if (APPLE) set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}") set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}") set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}") - set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTEABLE}) + set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTABLE}) set(MACOSX_BUNDLE_ICON_FILE mix) include(BundleUtilities) - add_executable(${EXECUTEABLE} MACOSX_BUNDLE ${SRC_LIST} ${HEADERS} ${UI_RESOURCES}) - set_target_properties(${EXECUTEABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") - SET_SOURCE_FILES_PROPERTIES(${EXECUTEABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) + add_executable(${EXECUTABLE} MACOSX_BUNDLE ${SRC_LIST} ${HEADERS} ${UI_RESOURCES}) + set_target_properties(${EXECUTABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") + SET_SOURCE_FILES_PROPERTIES(${EXECUTABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) SET_SOURCE_FILES_PROPERTIES(${MACOSX_BUNDLE_ICON_FILE}.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") else () - set(EXECUTEABLE mix) - add_executable(${EXECUTEABLE} ${SRC_LIST} ${HEADERS} ${UI_RESOURCES}) + set(EXECUTABLE mix) + add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS} ${UI_RESOURCES}) endif () -target_link_libraries(${EXECUTEABLE} Qt5::Core) -target_link_libraries(${EXECUTEABLE} Qt5::Gui) -target_link_libraries(${EXECUTEABLE} webthree) -target_link_libraries(${EXECUTEABLE} qethereum) -target_link_libraries(${EXECUTEABLE} ethereum) -target_link_libraries(${EXECUTEABLE} evm) -target_link_libraries(${EXECUTEABLE} ethcore) -target_link_libraries(${EXECUTEABLE} devcrypto) -target_link_libraries(${EXECUTEABLE} secp256k1) -target_link_libraries(${EXECUTEABLE} serpent) -target_link_libraries(${EXECUTEABLE} lll) -target_link_libraries(${EXECUTEABLE} solidity) -target_link_libraries(${EXECUTEABLE} evmcore) -target_link_libraries(${EXECUTEABLE} devcore) -target_link_libraries(${EXECUTEABLE} web3jsonrpc) -target_link_libraries(${EXECUTEABLE} jsqrc) +target_link_libraries(${EXECUTABLE} Qt5::Core) +target_link_libraries(${EXECUTABLE} Qt5::Gui) +target_link_libraries(${EXECUTABLE} webthree) +target_link_libraries(${EXECUTABLE} qethereum) +target_link_libraries(${EXECUTABLE} ethereum) +target_link_libraries(${EXECUTABLE} evm) +target_link_libraries(${EXECUTABLE} ethcore) +target_link_libraries(${EXECUTABLE} devcrypto) +target_link_libraries(${EXECUTABLE} secp256k1) +target_link_libraries(${EXECUTABLE} serpent) +target_link_libraries(${EXECUTABLE} lll) +target_link_libraries(${EXECUTABLE} solidity) +target_link_libraries(${EXECUTABLE} evmcore) +target_link_libraries(${EXECUTABLE} devcore) +target_link_libraries(${EXECUTABLE} web3jsonrpc) +target_link_libraries(${EXECUTABLE} jsqrc) if (APPLE) # First have qt5 install plugins and frameworks - add_custom_command(TARGET ${EXECUTEABLE} POST_BUILD - COMMAND ${CMAKE_DEPENDENCY_INSTALL_DIR}/bin/macdeployqt -qmldir=${CMAKE_CURRENT_SOURCE_DIR}/qml ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTEABLE}.app + add_custom_command(TARGET ${EXECUTABLE} POST_BUILD + COMMAND ${CMAKE_DEPENDENCY_INSTALL_DIR}/bin/macdeployqt -qmldir=${CMAKE_CURRENT_SOURCE_DIR}/qml ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) # This tool and next will inspect linked libraries in order to determine which dependencies are required if (${CMAKE_CFG_INTDIR} STREQUAL ".") - set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTEABLE}.app") + set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE}.app") else () - set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/\$ENV{CONFIGURATION}/${EXECUTEABLE}.app") + set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/\$ENV{CONFIGURATION}/${EXECUTABLE}.app") endif () install(CODE " include(BundleUtilities) @@ -81,5 +81,6 @@ if (APPLE) endif () ") else() - install( TARGETS ${EXECUTEABLE} RUNTIME DESTINATION bin) + install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin) endif () + diff --git a/neth/CMakeLists.txt b/neth/CMakeLists.txt index 4dd49874d..731f1e4fc 100644 --- a/neth/CMakeLists.txt +++ b/neth/CMakeLists.txt @@ -2,52 +2,31 @@ cmake_policy(SET CMP0015 NEW) aux_source_directory(. SRC_LIST) -include_directories(..) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) include_directories(${LEVELDB_INCLUDE_DIR}) +include_directories(..) set(EXECUTABLE neth) add_executable(${EXECUTABLE} ${SRC_LIST}) -target_link_libraries(${EXECUTABLE} webthree) -target_link_libraries(${EXECUTABLE} ethereum) -target_link_libraries(${EXECUTABLE} secp256k1) -target_link_libraries(${EXECUTABLE} gmp) +add_dependencies(${EXECUTABLE} BuildInfo.h) + +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) + if(MINIUPNPC_FOUND) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) + if(JSON_RPC_CPP_FOUND) target_link_libraries(${EXECUTABLE} web3jsonrpc) endif() -if ("${TARGET_PLATFORM}" STREQUAL "w64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") - target_link_libraries(${EXECUTABLE} gcc) - target_link_libraries(${EXECUTABLE} gdi32) - target_link_libraries(${EXECUTABLE} ws2_32) - target_link_libraries(${EXECUTABLE} mswsock) - target_link_libraries(${EXECUTABLE} shlwapi) - target_link_libraries(${EXECUTABLE} iphlpapi) - target_link_libraries(${EXECUTABLE} cryptopp) - target_link_libraries(${EXECUTABLE} ncurses) - target_link_libraries(${EXECUTABLE} form) - target_link_libraries(${EXECUTABLE} boost_system-mt-s) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) - target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) - set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) -elseif (UNIX) - target_link_libraries(${EXECUTABLE} ncurses) - target_link_libraries(${EXECUTABLE} form) -else () - target_link_libraries(${EXECUTABLE} boost_system) - target_link_libraries(${EXECUTABLE} boost_filesystem) - target_link_libraries(${EXECUTABLE} ncurses) - target_link_libraries(${EXECUTABLE} form) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -endif () +target_link_libraries(${EXECUTABLE} webthree) +target_link_libraries(${EXECUTABLE} ethereum) +target_link_libraries(${EXECUTABLE} secp256k1) +target_link_libraries(${EXECUTABLE} ncurses) +target_link_libraries(${EXECUTABLE} form) install( TARGETS ${EXECUTABLE} DESTINATION bin ) diff --git a/third/CMakeLists.txt b/third/CMakeLists.txt index de0581067..98efde545 100644 --- a/third/CMakeLists.txt +++ b/third/CMakeLists.txt @@ -40,6 +40,8 @@ else () add_executable(${EXECUTABLE} Main.ui ${SRC_LIST} ${HEADERS}) endif () +add_dependencies(${EXECUTABLE} BuildInfo.h) + target_link_libraries(${EXECUTABLE} Qt5::Core) target_link_libraries(${EXECUTABLE} webthree) target_link_libraries(${EXECUTABLE} qethereum) From 8098a94941743962a12497345fbf6912b06fc59a Mon Sep 17 00:00:00 2001 From: ethdev Date: Wed, 10 Dec 2014 11:53:43 +0100 Subject: [PATCH 112/277] io_service is 2 again --- libp2p/Host.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 52ceb5df3..93a6ce672 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -42,7 +42,7 @@ Host::Host(std::string const& _clientVersion, NetworkPreferences const& _n, bool m_clientVersion(_clientVersion), m_netPrefs(_n), m_ifAddresses(Network::getInterfaceAddresses()), - m_ioService(), + m_ioService(2), m_acceptorV4(m_ioService), m_key(KeyPair::create()) { From 3fae34304125dd7206cb0033a47ce6d90c5de95a Mon Sep 17 00:00:00 2001 From: ethdev Date: Wed, 10 Dec 2014 12:31:09 +0100 Subject: [PATCH 113/277] cmake improvements on windows --- CMakeLists.txt | 3 +++ alethzero/CMakeLists.txt | 2 ++ libjsqrc/CMakeLists.txt | 4 +++- libqethereum/CMakeLists.txt | 4 +++- libqethereum/QEthereum.cpp | 8 -------- libqethereum/QmlEthereum.cpp | 8 -------- mix/CMakeLists.txt | 4 +++- third/CMakeLists.txt | 2 ++ third/MainWin.cpp | 12 ------------ 9 files changed, 16 insertions(+), 31 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3aad38f71..00f24c863 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,8 @@ # cmake global cmake_minimum_required(VERSION 2.8.9) +# let cmake autolink dependencies on windows +# it's specified globally, cause qt libraries requires that on windows and they are also found globally +cmake_policy(SET CMP0020 NEW) project(ethereum) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index 47d1f73e8..0ea0ef8a6 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -1,4 +1,6 @@ cmake_policy(SET CMP0015 NEW) +# let cmake autolink dependencies on windows +cmake_policy(SET CMP0020 NEW) # this policy was introduced in cmake 3.0 # remove if, once 3.0 will be used on unix if (APPLE) diff --git a/libjsqrc/CMakeLists.txt b/libjsqrc/CMakeLists.txt index 9533ddd1a..58dcb76ce 100644 --- a/libjsqrc/CMakeLists.txt +++ b/libjsqrc/CMakeLists.txt @@ -1,7 +1,9 @@ cmake_policy(SET CMP0015 NEW) +# let cmake autolink dependencies on windows +cmake_policy(SET CMP0020 NEW) # this policy was introduced in cmake 3.0 # remove if, once 3.0 will be used on unix -if (APPLE) +if (${CMAKE_MAJOR_VERSION} GREATER 2) cmake_policy(SET CMP0043 OLD) endif() set(CMAKE_AUTOMOC OFF) diff --git a/libqethereum/CMakeLists.txt b/libqethereum/CMakeLists.txt index 9bc8c5de8..9585943f0 100644 --- a/libqethereum/CMakeLists.txt +++ b/libqethereum/CMakeLists.txt @@ -1,7 +1,9 @@ cmake_policy(SET CMP0015 NEW) +# let cmake autolink dependencies on windows +cmake_policy(SET CMP0020 NEW) # this policy was introduced in cmake 3.0 # remove if, once 3.0 will be used on unix -if (APPLE) +if (${CMAKE_MAJOR_VERSION} GREATER 2) # old policy do not use MACOSX_RPATH cmake_policy(SET CMP0042 OLD) cmake_policy(SET CMP0043 OLD) diff --git a/libqethereum/QEthereum.cpp b/libqethereum/QEthereum.cpp index 5e5253829..daf773a22 100644 --- a/libqethereum/QEthereum.cpp +++ b/libqethereum/QEthereum.cpp @@ -227,11 +227,3 @@ void QWebThreeConnector::onProcessData(QString const& _json, QString const& _add OnRequest(_json.toStdString(), (void*)&_addInfo); } -// extra bits needed to link on VS -#ifdef _MSC_VER - -// include moc file, ofuscated to hide from automoc -#include\ -"moc_QEthereum.cpp" - -#endif diff --git a/libqethereum/QmlEthereum.cpp b/libqethereum/QmlEthereum.cpp index b1b926f42..812247b36 100644 --- a/libqethereum/QmlEthereum.cpp +++ b/libqethereum/QmlEthereum.cpp @@ -178,11 +178,3 @@ void QmlEthereum::transact(Secret _secret, Address _dest, u256 _amount, u256 _ga #endif -// extra bits needed to link on VS -#ifdef _MSC_VER - -// include moc file, ofuscated to hide from automoc -#include\ -"moc_QmlEthereum.cpp" - -#endif diff --git a/mix/CMakeLists.txt b/mix/CMakeLists.txt index 3980f5642..ce8099ce0 100644 --- a/mix/CMakeLists.txt +++ b/mix/CMakeLists.txt @@ -1,7 +1,9 @@ cmake_policy(SET CMP0015 NEW) +# let cmake autolink dependencies on windows +cmake_policy(SET CMP0020 NEW) # this policy was introduced in cmake 3.0 # remove if, once 3.0 will be used on unix -if (APPLE) +if (${CMAKE_MAJOR_VERSION} GREATER 2) cmake_policy(SET CMP0043 OLD) endif() diff --git a/third/CMakeLists.txt b/third/CMakeLists.txt index 98efde545..5237e471e 100644 --- a/third/CMakeLists.txt +++ b/third/CMakeLists.txt @@ -1,4 +1,6 @@ cmake_policy(SET CMP0015 NEW) +# let cmake autolink dependencies on windows +cmake_policy(SET CMP0020 NEW) # this policy was introduced in cmake 3.0 # remove if, once 3.0 will be used on unix if (APPLE) diff --git a/third/MainWin.cpp b/third/MainWin.cpp index 71192d630..894f1af0f 100644 --- a/third/MainWin.cpp +++ b/third/MainWin.cpp @@ -611,15 +611,3 @@ void Main::on_mine_triggered() else ethereum()->stopMining(); } - -// extra bits needed to link on VS -#ifdef _MSC_VER - -// include moc file, ofuscated to hide from automoc -#include\ -"moc_MainWin.cpp" - -#include\ -"moc_MiningView.cpp" - -#endif From 48dfbaf3c9c3a32f9c5f2f2fee2ed948a19ee08d Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 10 Dec 2014 12:49:12 +0100 Subject: [PATCH 114/277] updated cmake policies --- libdevcore/CMakeLists.txt | 2 +- libdevcrypto/CMakeLists.txt | 2 +- libethcore/CMakeLists.txt | 2 +- libethereum/CMakeLists.txt | 2 +- libevm/CMakeLists.txt | 2 +- libevmcore/CMakeLists.txt | 2 +- liblll/CMakeLists.txt | 2 +- libp2p/CMakeLists.txt | 2 +- libserpent/CMakeLists.txt | 2 +- libsolidity/CMakeLists.txt | 2 +- libweb3jsonrpc/CMakeLists.txt | 2 +- libwebthree/CMakeLists.txt | 2 +- libwhisper/CMakeLists.txt | 2 +- secp256k1/CMakeLists.txt | 2 +- third/CMakeLists.txt | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/libdevcore/CMakeLists.txt b/libdevcore/CMakeLists.txt index b1a21470f..cb5f8eb3f 100644 --- a/libdevcore/CMakeLists.txt +++ b/libdevcore/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_policy(SET CMP0015 OLD) # this policy was introduced in cmake 3.0 # remove if, once 3.0 will be used on unix -if (APPLE) +if (${CMAKE_MAJOR_VERSION} GREATER 2) # old policy do not use MACOSX_RPATH cmake_policy(SET CMP0042 OLD) endif() diff --git a/libdevcrypto/CMakeLists.txt b/libdevcrypto/CMakeLists.txt index 059cae7f9..f5661bab1 100644 --- a/libdevcrypto/CMakeLists.txt +++ b/libdevcrypto/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_policy(SET CMP0015 OLD) # this policy was introduced in cmake 3.0 # remove if, once 3.0 will be used on unix -if (APPLE) +if (${CMAKE_MAJOR_VERSION} GREATER 2) # old policy do not use MACOSX_RPATH cmake_policy(SET CMP0042 OLD) endif() diff --git a/libethcore/CMakeLists.txt b/libethcore/CMakeLists.txt index b2e90a622..ede6eb087 100644 --- a/libethcore/CMakeLists.txt +++ b/libethcore/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_policy(SET CMP0015 NEW) # this policy was introduced in cmake 3.0 # remove if, once 3.0 will be used on unix -if (APPLE) +if (${CMAKE_MAJOR_VERSION} GREATER 2) # old policy do not use MACOSX_RPATH cmake_policy(SET CMP0042 OLD) endif() diff --git a/libethereum/CMakeLists.txt b/libethereum/CMakeLists.txt index 40c53a8a5..02cb8f96d 100644 --- a/libethereum/CMakeLists.txt +++ b/libethereum/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_policy(SET CMP0015 NEW) # this policy was introduced in cmake 3.0 # remove if, once 3.0 will be used on unix -if (APPLE) +if (${CMAKE_MAJOR_VERSION} GREATER 2) # old policy do not use MACOSX_RPATH cmake_policy(SET CMP0042 OLD) endif() diff --git a/libevm/CMakeLists.txt b/libevm/CMakeLists.txt index a4a8c4f3c..e62501f93 100644 --- a/libevm/CMakeLists.txt +++ b/libevm/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_policy(SET CMP0015 NEW) # this policy was introduced in cmake 3.0 # remove if, once 3.0 will be used on unix -if (APPLE) +if (${CMAKE_MAJOR_VERSION} GREATER 2) # old policy do not use MACOSX_RPATH cmake_policy(SET CMP0042 OLD) endif() diff --git a/libevmcore/CMakeLists.txt b/libevmcore/CMakeLists.txt index 737df945b..21dee65c2 100644 --- a/libevmcore/CMakeLists.txt +++ b/libevmcore/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_policy(SET CMP0015 NEW) # this policy was introduced in cmake 3.0 # remove if, once 3.0 will be used on unix -if (APPLE) +if (${CMAKE_MAJOR_VERSION} GREATER 2) # old policy do not use MACOSX_RPATH cmake_policy(SET CMP0042 OLD) endif() diff --git a/liblll/CMakeLists.txt b/liblll/CMakeLists.txt index 908b8caf3..28e5cb758 100644 --- a/liblll/CMakeLists.txt +++ b/liblll/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_policy(SET CMP0015 NEW) # this policy was introduced in cmake 3.0 # remove if, once 3.0 will be used on unix -if (APPLE) +if (${CMAKE_MAJOR_VERSION} GREATER 2) # old policy do not use MACOSX_RPATH cmake_policy(SET CMP0042 OLD) endif() diff --git a/libp2p/CMakeLists.txt b/libp2p/CMakeLists.txt index 5ace09dda..8c5d49da0 100644 --- a/libp2p/CMakeLists.txt +++ b/libp2p/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_policy(SET CMP0015 NEW) # this policy was introduced in cmake 3.0 # remove if, once 3.0 will be used on unix -if (APPLE) +if (${CMAKE_MAJOR_VERSION} GREATER 2) # old policy do not use MACOSX_RPATH cmake_policy(SET CMP0042 OLD) endif() diff --git a/libserpent/CMakeLists.txt b/libserpent/CMakeLists.txt index 4d4a25e58..e28aeb032 100644 --- a/libserpent/CMakeLists.txt +++ b/libserpent/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_policy(SET CMP0015 NEW) # this policy was introduced in cmake 3.0 # remove if, once 3.0 will be used on unix -if (APPLE) +if (${CMAKE_MAJOR_VERSION} GREATER 2) # old policy do not use MACOSX_RPATH cmake_policy(SET CMP0042 OLD) endif() diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index ad93609f0..44a7b9bb2 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_policy(SET CMP0015 NEW) # this policy was introduced in cmake 3.0 # remove if, once 3.0 will be used on unix -if (APPLE) +if (${CMAKE_MAJOR_VERSION} GREATER 2) # old policy do not use MACOSX_RPATH cmake_policy(SET CMP0042 OLD) endif() diff --git a/libweb3jsonrpc/CMakeLists.txt b/libweb3jsonrpc/CMakeLists.txt index 5ddbc186f..3c5d589ca 100644 --- a/libweb3jsonrpc/CMakeLists.txt +++ b/libweb3jsonrpc/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_policy(SET CMP0015 NEW) # this policy was introduced in cmake 3.0 # remove if, once 3.0 will be used on unix -if (APPLE) +if (${CMAKE_MAJOR_VERSION} GREATER 2) # old policy do not use MACOSX_RPATH cmake_policy(SET CMP0042 OLD) endif() diff --git a/libwebthree/CMakeLists.txt b/libwebthree/CMakeLists.txt index 661786d1a..20b4ee603 100644 --- a/libwebthree/CMakeLists.txt +++ b/libwebthree/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_policy(SET CMP0015 NEW) # this policy was introduced in cmake 3.0 # remove if, once 3.0 will be used on unix -if (APPLE) +if (${CMAKE_MAJOR_VERSION} GREATER 2) # old policy do not use MACOSX_RPATH cmake_policy(SET CMP0042 OLD) endif() diff --git a/libwhisper/CMakeLists.txt b/libwhisper/CMakeLists.txt index 89650db88..b0bb20b2b 100644 --- a/libwhisper/CMakeLists.txt +++ b/libwhisper/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_policy(SET CMP0015 NEW) # this policy was introduced in cmake 3.0 # remove if, once 3.0 will be used on unix -if (APPLE) +if (${CMAKE_MAJOR_VERSION} GREATER 2) # old policy do not use MACOSX_RPATH cmake_policy(SET CMP0042 OLD) endif() diff --git a/secp256k1/CMakeLists.txt b/secp256k1/CMakeLists.txt index beeee598f..cc4f1b87c 100644 --- a/secp256k1/CMakeLists.txt +++ b/secp256k1/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_policy(SET CMP0015 NEW) # this policy was introduced in cmake 3.0 # remove if, once 3.0 will be used on unix -if (APPLE) +if (${CMAKE_MAJOR_VERSION} GREATER 2) # old policy do not use MACOSX_RPATH cmake_policy(SET CMP0042 OLD) endif() diff --git a/third/CMakeLists.txt b/third/CMakeLists.txt index 5237e471e..b28210719 100644 --- a/third/CMakeLists.txt +++ b/third/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_policy(SET CMP0015 NEW) cmake_policy(SET CMP0020 NEW) # this policy was introduced in cmake 3.0 # remove if, once 3.0 will be used on unix -if (APPLE) +if (${CMAKE_MAJOR_VERSION} GREATER 2) cmake_policy(SET CMP0043 OLD) endif() From 17252cecf1fff3750341e2f3b6b33ef874449538 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 10 Dec 2014 14:16:22 +0100 Subject: [PATCH 115/277] minimum cmake version upgraded to 2.8.12 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 00f24c863..a4ed1c400 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ # cmake global -cmake_minimum_required(VERSION 2.8.9) +cmake_minimum_required(VERSION 2.8.12) # let cmake autolink dependencies on windows # it's specified globally, cause qt libraries requires that on windows and they are also found globally cmake_policy(SET CMP0020 NEW) From 781d58d705ab02dcf934c88789b0e02042fc062e Mon Sep 17 00:00:00 2001 From: Christian Date: Tue, 9 Dec 2014 18:46:18 +0100 Subject: [PATCH 116/277] String types. --- libsolidity/AST.cpp | 2 +- libsolidity/Compiler.cpp | 6 +++- libsolidity/ExpressionCompiler.cpp | 22 +++++++++--- libsolidity/ExpressionCompiler.h | 3 +- libsolidity/Token.h | 32 +++++++++++++++++ libsolidity/Types.cpp | 43 ++++++++++++++++++++++- libsolidity/Types.h | 31 ++++++++++++++++- test/solidityEndToEndTest.cpp | 56 ++++++++++++++++++++++++++++++ 8 files changed, 186 insertions(+), 9 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 697ffe8e3..97b39eed0 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -582,7 +582,7 @@ void Literal::checkTypeRequirements() { m_type = Type::forLiteral(*this); if (!m_type) - BOOST_THROW_EXCEPTION(createTypeError("Literal value too large.")); + BOOST_THROW_EXCEPTION(createTypeError("Literal value too large or too small.")); } } diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index a8a074034..781f36800 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -142,6 +142,9 @@ unsigned Compiler::appendCalldataUnpacker(FunctionDefinition const& _function, b << errinfo_comment("Type " + var->getType()->toString() + " not yet supported.")); if (numBytes == 32) m_context << u256(dataOffset) << load; + else if (var->getType()->getCategory() == Type::Category::STRING) + m_context << (u256(1) << ((32 - numBytes) * 8)) << eth::Instruction::DUP1 + << u256(dataOffset) << load << eth::Instruction::DIV << eth::Instruction::MUL; else m_context << (u256(1) << ((32 - numBytes) * 8)) << u256(dataOffset) << load << eth::Instruction::DIV; @@ -166,7 +169,8 @@ void Compiler::appendReturnValuePacker(FunctionDefinition const& _function) << errinfo_comment("Type " + paramType.toString() + " not yet supported.")); CompilerUtils(m_context).copyToStackTop(stackDepth, paramType); if (numBytes != 32) - m_context << (u256(1) << ((32 - numBytes) * 8)) << eth::Instruction::MUL; + if (paramType.getCategory() != Type::Category::STRING) + m_context << (u256(1) << ((32 - numBytes) * 8)) << eth::Instruction::MUL; m_context << u256(dataOffset) << eth::Instruction::MSTORE; stackDepth -= paramType.getSizeOnStack(); dataOffset += numBytes; diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index f1086c143..5e688f6bd 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -226,7 +226,8 @@ bool ExpressionCompiler::visit(FunctionCall& _functionCall) << errinfo_sourceLocation(arguments[i]->getLocation()) << errinfo_comment("Type " + type.toString() + " not yet supported.")); if (numBytes != 32) - m_context << (u256(1) << ((32 - numBytes) * 8)) << eth::Instruction::MUL; + if (type.getCategory() != Type::Category::STRING) + m_context << (u256(1) << ((32 - numBytes) * 8)) << eth::Instruction::MUL; m_context << u256(dataOffset) << eth::Instruction::MSTORE; dataOffset += numBytes; } @@ -243,8 +244,15 @@ bool ExpressionCompiler::visit(FunctionCall& _functionCall) if (retSize == 32) m_context << u256(0) << eth::Instruction::MLOAD; else if (retSize > 0) - m_context << (u256(1) << ((32 - retSize) * 8)) - << u256(0) << eth::Instruction::MLOAD << eth::Instruction::DIV; + { + if (function.getReturnParameterTypes().front()->getCategory() == Type::Category::STRING) + m_context << (u256(1) << ((32 - retSize) * 8)) << eth::Instruction::DUP1 + << u256(0) << eth::Instruction::MLOAD + << eth::Instruction::DIV << eth::Instruction::MUL; + else + m_context << (u256(1) << ((32 - retSize) * 8)) + << u256(0) << eth::Instruction::MLOAD << eth::Instruction::DIV; + } break; } case Location::SEND: @@ -411,10 +419,11 @@ void ExpressionCompiler::endVisit(Literal& _literal) { case Type::Category::INTEGER: case Type::Category::BOOL: + case Type::Category::STRING: m_context << _literal.getType()->literalValue(_literal); break; default: - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Only integer and boolean literals implemented for now.")); + BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Only integer, boolean and string literals implemented for now.")); } } @@ -550,6 +559,11 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con return; if (_typeOnStack.getCategory() == Type::Category::INTEGER) appendHighBitsCleanup(dynamic_cast(_typeOnStack)); + else if (_typeOnStack.getCategory() == Type::Category::STRING) + { + // nothing to do, strings are high-order-bit-aligned + //@todo clear lower-order bytes if we allow explicit conversion to shorter strings + } else if (_typeOnStack != _targetType) // All other types should not be convertible to non-equal types. BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid type conversion requested.")); diff --git a/libsolidity/ExpressionCompiler.h b/libsolidity/ExpressionCompiler.h index 966be30e2..386a71165 100644 --- a/libsolidity/ExpressionCompiler.h +++ b/libsolidity/ExpressionCompiler.h @@ -35,6 +35,7 @@ namespace solidity { class CompilerContext; class Type; class IntegerType; +class StaticStringType; /** * Compiler for expressions, i.e. converts an AST tree whose root is an Expression into a stream @@ -75,7 +76,7 @@ private: /// @} /// Appends an implicit or explicit type conversion. For now this comprises only erasing - /// higher-order bits (@see appendHighBitCleanup) when widening integer types. + /// higher-order bits (@see appendHighBitCleanup) when widening integer. /// If @a _cleanupNeeded, high order bits cleanup is also done if no type conversion would be /// necessary. void appendTypeConversion(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded = false); diff --git a/libsolidity/Token.h b/libsolidity/Token.h index f1a94af35..f9ded3114 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -269,6 +269,38 @@ namespace solidity K(ADDRESS, "address", 0) \ K(BOOL, "bool", 0) \ K(STRING_TYPE, "string", 0) \ + K(STRING1, "string1", 0) \ + K(STRING2, "string2", 0) \ + K(STRING3, "string3", 0) \ + K(STRING4, "string4", 0) \ + K(STRING5, "string5", 0) \ + K(STRING6, "string6", 0) \ + K(STRING7, "string7", 0) \ + K(STRING8, "string8", 0) \ + K(STRING9, "string9", 0) \ + K(STRING10, "string10", 0) \ + K(STRING11, "string11", 0) \ + K(STRING12, "string12", 0) \ + K(STRING13, "string13", 0) \ + K(STRING14, "string14", 0) \ + K(STRING15, "string15", 0) \ + K(STRING16, "string16", 0) \ + K(STRING17, "string17", 0) \ + K(STRING18, "string18", 0) \ + K(STRING19, "string19", 0) \ + K(STRING20, "string20", 0) \ + K(STRING21, "string21", 0) \ + K(STRING22, "string22", 0) \ + K(STRING23, "string23", 0) \ + K(STRING24, "string24", 0) \ + K(STRING25, "string25", 0) \ + K(STRING26, "string26", 0) \ + K(STRING27, "string27", 0) \ + K(STRING28, "string28", 0) \ + K(STRING29, "string29", 0) \ + K(STRING30, "string30", 0) \ + K(STRING31, "string31", 0) \ + K(STRING32, "string32", 0) \ K(TEXT, "text", 0) \ K(REAL, "real", 0) \ K(UREAL, "ureal", 0) \ diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 3829016f5..f7446dea9 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -53,6 +53,8 @@ shared_ptr Type::fromElementaryTypeName(Token::Value _typeToken) return make_shared(0, IntegerType::Modifier::ADDRESS); else if (_typeToken == Token::BOOL) return make_shared(); + else if (Token::STRING1 <= _typeToken && _typeToken <= Token::STRING32) + return make_shared(int(_typeToken) - int(Token::STRING1) + 1); else BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unable to convert elementary typename " + std::string(Token::toString(_typeToken)) + " to type.")); @@ -91,7 +93,8 @@ shared_ptr Type::forLiteral(Literal const& _literal) case Token::NUMBER: return IntegerType::smallestTypeForLiteral(_literal.getValue()); case Token::STRING_LITERAL: - return shared_ptr(); // @todo add string literals + //@todo put larger strings into dynamic strings + return StaticStringType::smallestTypeForLiteral(_literal.getValue()); default: return shared_ptr(); } @@ -194,6 +197,44 @@ const MemberList IntegerType::AddressMemberList = {"send", make_shared(TypePointers({make_shared(256)}), TypePointers(), FunctionType::Location::SEND)}}); +shared_ptr StaticStringType::smallestTypeForLiteral(string const& _literal) +{ + if (0 < _literal.length() && _literal.length() <= 32) + return make_shared(_literal.length()); + return shared_ptr(); +} + +StaticStringType::StaticStringType(int _bytes): m_bytes(_bytes) +{ + if (asserts(m_bytes > 0 && m_bytes <= 32)) + BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid byte number for static string type: " + + dev::toString(m_bytes))); +} + +bool StaticStringType::isImplicitlyConvertibleTo(Type const& _convertTo) const +{ + if (_convertTo.getCategory() != getCategory()) + return false; + StaticStringType const& convertTo = dynamic_cast(_convertTo); + return convertTo.m_bytes >= m_bytes; +} + +bool StaticStringType::operator==(Type const& _other) const +{ + if (_other.getCategory() != getCategory()) + return false; + StaticStringType const& other = dynamic_cast(_other); + return other.m_bytes == m_bytes; +} + +u256 StaticStringType::literalValue(const Literal& _literal) const +{ + u256 value = 0; + for (char c: _literal.getValue()) + value = (value << 8) | byte(c); + return value << ((32 - _literal.getValue().length()) * 8); +} + bool BoolType::isExplicitlyConvertibleTo(Type const& _convertTo) const { // conversion to integer is fine, but not to address diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 8e2f4803b..c96d0bb1f 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -36,7 +36,7 @@ namespace dev namespace solidity { -// @todo realMxN, string +// @todo realMxN, dynamic strings, text, arrays class Type; // forward using TypePointer = std::shared_ptr; @@ -178,6 +178,35 @@ private: static const MemberList AddressMemberList; }; +/** + * String type with fixed length, up to 32 bytes. + */ +class StaticStringType: public Type +{ +public: + virtual Category getCategory() const override { return Category::STRING; } + + /// @returns the smallest string type for the given literal or an empty pointer + /// if no type fits. + static std::shared_ptr smallestTypeForLiteral(std::string const& _literal); + + StaticStringType(int _bytes); + + virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; + virtual bool operator==(Type const& _other) const override; + + virtual unsigned getCalldataEncodedSize() const override { return m_bytes; } + virtual bool isValueType() const override { return true; } + + virtual std::string toString() const override { return "string" + dev::toString(m_bytes); } + virtual u256 literalValue(Literal const& _literal) const override; + + int getNumBytes() const { return m_bytes; } + +private: + int m_bytes; +}; + /** * The boolean type. */ diff --git a/test/solidityEndToEndTest.cpp b/test/solidityEndToEndTest.cpp index 3c2bb0814..940ccac63 100644 --- a/test/solidityEndToEndTest.cpp +++ b/test/solidityEndToEndTest.cpp @@ -482,6 +482,34 @@ BOOST_AUTO_TEST_CASE(small_signed_types) testSolidityAgainstCpp(0, small_signed_types_cpp); } +BOOST_AUTO_TEST_CASE(strings) +{ + char const* sourceCode = "contract test {\n" + " function fixed() returns(string32 ret) {\n" + " return \"abc\\x00\\xff__\";\n" + " }\n" + " function pipeThrough(string2 small, bool one) returns(string16 large, bool oneRet) {\n" + " oneRet = one;\n" + " large = small;\n" + " }\n" + "}\n"; + compileAndRun(sourceCode); + bytes expectation(32, 0); + expectation[0] = byte('a'); + expectation[1] = byte('b'); + expectation[2] = byte('c'); + expectation[3] = byte(0); + expectation[4] = byte(0xff); + expectation[5] = byte('_'); + expectation[6] = byte('_'); + BOOST_CHECK(callContractFunction(0, bytes()) == expectation); + expectation = bytes(17, 0); + expectation[0] = 0; + expectation[1] = 2; + expectation[16] = 1; + BOOST_CHECK(callContractFunction(1, bytes({0x00, 0x02, 0x01})) == expectation); +} + BOOST_AUTO_TEST_CASE(state_smoke_test) { char const* sourceCode = "contract test {\n" @@ -1060,6 +1088,34 @@ BOOST_AUTO_TEST_CASE(inter_contract_calls_with_local_vars) BOOST_REQUIRE(callContractFunction(0, a, b) == toBigEndian(a * b + 9)); } +BOOST_AUTO_TEST_CASE(strings_in_calls) +{ + char const* sourceCode = R"( + contract Helper { + function invoke(string3 x, bool stop) returns (string4 ret) { + return x; + } + } + contract Main { + Helper h; + function callHelper(string2 x, bool stop) returns (string5 ret) { + return h.invoke(x, stop); + } + function getHelper() returns (address addr) { + return address(h); + } + function setHelper(address addr) { + h = Helper(addr); + } + })"; + compileAndRun(sourceCode, 0, "Helper"); + u160 const helperAddress = m_contractAddress; + compileAndRun(sourceCode, 0, "Main"); + BOOST_REQUIRE(callContractFunction(2, helperAddress) == bytes()); + BOOST_REQUIRE(callContractFunction(1, helperAddress) == toBigEndian(helperAddress)); + BOOST_CHECK(callContractFunction(0, bytes({0, 'a', 1})) == bytes({0, 'a', 0, 0, 0})); +} + BOOST_AUTO_TEST_SUITE_END() } From 0aefbb6b2defd2f46d52903a33917a302e8ea909 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 10 Dec 2014 16:56:30 +0100 Subject: [PATCH 117/277] recent changes from solc working on macos --- cmake/EthDependencies.cmake | 2 +- solc/CMakeLists.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 4877b06d5..8d65bc62b 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -125,7 +125,7 @@ elseif (UNIX) endif() -find_package(Boost 1.54.0 REQUIRED COMPONENTS thread date_time system regex chrono filesystem unit_test_framework) +find_package(Boost 1.54.0 REQUIRED COMPONENTS thread date_time system regex chrono filesystem unit_test_framework program_options) message(" - boost header: ${Boost_INCLUDE_DIRS}") message(" - boost lib : ${Boost_LIBRARIES}") diff --git a/solc/CMakeLists.txt b/solc/CMakeLists.txt index e7cc5a1a6..cf1e42572 100644 --- a/solc/CMakeLists.txt +++ b/solc/CMakeLists.txt @@ -11,8 +11,8 @@ set(EXECUTABLE solc) file(GLOB HEADERS "*.h") add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) -target_link_libraries(${EXECUTABLE} boost_filesystem) -target_link_libraries(${EXECUTABLE} boost_program_options) +target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY_RELEASE}) +target_link_libraries(${EXECUTABLE} ${Boost_PROGRAM_OPTIONS_LIBRARY_RELEASE}) target_link_libraries(${EXECUTABLE} solidity) install( TARGETS ${EXECUTABLE} DESTINATION bin ) From d608ebf36b758c67d173d271ad7973c566a1b9b6 Mon Sep 17 00:00:00 2001 From: ethdev Date: Wed, 10 Dec 2014 16:58:05 +0100 Subject: [PATCH 118/277] windows boost compiling with program_options module --- extdep/compile/boost.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extdep/compile/boost.cmake b/extdep/compile/boost.cmake index c87c907b7..f38c70f02 100644 --- a/extdep/compile/boost.cmake +++ b/extdep/compile/boost.cmake @@ -5,7 +5,7 @@ set(boost_address_model) # on windows 64: # set(boost_address_model address-model=64) -set(boost_targets --with-filesystem --with-system --with-thread --with-date_time --with-regex --with-test --with-chrono) +set(boost_targets --with-filesystem --with-system --with-thread --with-date_time --with-regex --with-test --with-chrono --with-program_options) ExternalProject_Add(boost URL http://downloads.sourceforge.net/project/boost/boost/1.55.0/boost_1_55_0.tar.gz BINARY_DIR boost-prefix/src/boost From 0a4ed446797ac43255da00f5aee979476cf72025 Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 10 Dec 2014 17:15:10 +0100 Subject: [PATCH 119/277] Tests for empty and too long strings. --- test/solidityNameAndTypeResolution.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/solidityNameAndTypeResolution.cpp b/test/solidityNameAndTypeResolution.cpp index 783972296..7357471cc 100644 --- a/test/solidityNameAndTypeResolution.cpp +++ b/test/solidityNameAndTypeResolution.cpp @@ -226,6 +226,22 @@ BOOST_AUTO_TEST_CASE(type_inference_explicit_conversion) BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); } +BOOST_AUTO_TEST_CASE(empty_string_literal) +{ + char const* text = "contract test {\n" + " function f() { var x = \"\"; }" + "}\n"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + +BOOST_AUTO_TEST_CASE(large_string_literal) +{ + char const* text = "contract test {\n" + " function f() { var x = \"123456789012345678901234567890123\"; }" + "}\n"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + BOOST_AUTO_TEST_CASE(balance) { char const* text = "contract test {\n" From 584242357a86ad9ddd051a13d65373578f7a8fc7 Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 10 Dec 2014 17:15:17 +0100 Subject: [PATCH 120/277] Helper functions to access memory. --- libsolidity/Compiler.cpp | 17 ++++---------- libsolidity/CompilerUtils.cpp | 30 +++++++++++++++++++++++++ libsolidity/CompilerUtils.h | 12 ++++++++++ libsolidity/ExpressionCompiler.cpp | 36 +++++++++++++----------------- 4 files changed, 61 insertions(+), 34 deletions(-) diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index 781f36800..578d63bbd 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -130,7 +130,6 @@ unsigned Compiler::appendCalldataUnpacker(FunctionDefinition const& _function, b { // We do not check the calldata size, everything is zero-padded. unsigned dataOffset = 1; - eth::Instruction load = _fromMemory ? eth::Instruction::MLOAD : eth::Instruction::CALLDATALOAD; //@todo this can be done more efficiently, saving some CALLDATALOAD calls for (ASTPointer const& var: _function.getParameters()) @@ -140,14 +139,8 @@ unsigned Compiler::appendCalldataUnpacker(FunctionDefinition const& _function, b BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(var->getLocation()) << errinfo_comment("Type " + var->getType()->toString() + " not yet supported.")); - if (numBytes == 32) - m_context << u256(dataOffset) << load; - else if (var->getType()->getCategory() == Type::Category::STRING) - m_context << (u256(1) << ((32 - numBytes) * 8)) << eth::Instruction::DUP1 - << u256(dataOffset) << load << eth::Instruction::DIV << eth::Instruction::MUL; - else - m_context << (u256(1) << ((32 - numBytes) * 8)) << u256(dataOffset) - << load << eth::Instruction::DIV; + bool leftAligned = var->getType()->getCategory() == Type::Category::STRING; + CompilerUtils(m_context).loadFromMemory(dataOffset, numBytes, leftAligned, !_fromMemory); dataOffset += numBytes; } return dataOffset; @@ -168,10 +161,8 @@ void Compiler::appendReturnValuePacker(FunctionDefinition const& _function) << errinfo_sourceLocation(parameters[i]->getLocation()) << errinfo_comment("Type " + paramType.toString() + " not yet supported.")); CompilerUtils(m_context).copyToStackTop(stackDepth, paramType); - if (numBytes != 32) - if (paramType.getCategory() != Type::Category::STRING) - m_context << (u256(1) << ((32 - numBytes) * 8)) << eth::Instruction::MUL; - m_context << u256(dataOffset) << eth::Instruction::MSTORE; + bool const leftAligned = paramType.getCategory() == Type::Category::STRING; + CompilerUtils(m_context).storeInMemory(dataOffset, numBytes, leftAligned); stackDepth -= paramType.getSizeOnStack(); dataOffset += numBytes; } diff --git a/libsolidity/CompilerUtils.cpp b/libsolidity/CompilerUtils.cpp index d4dfbe3c0..0ee4a53cb 100644 --- a/libsolidity/CompilerUtils.cpp +++ b/libsolidity/CompilerUtils.cpp @@ -31,6 +31,36 @@ namespace dev namespace solidity { +void CompilerUtils::loadFromMemory(unsigned _offset, unsigned _bytes, bool _leftAligned, bool _fromCalldata) +{ + eth::Instruction load = _fromCalldata ? eth::Instruction::CALLDATALOAD : eth::Instruction::MLOAD; + if (asserts(0 < _bytes && _bytes <= 32)) + BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Memory load of 0 or more than 32 bytes requested.")); + if (_bytes == 32) + m_context << u256(_offset) << load; + else + { + // load data and add leading or trailing zeros by dividing/multiplying depending on alignment + u256 shiftFactor = u256(1) << ((32 - _bytes) * 8); + m_context << shiftFactor; + if (_leftAligned) + m_context << eth::Instruction::DUP1; + m_context << u256(_offset) << load << eth::Instruction::DIV; + if (_leftAligned) + m_context << eth::Instruction::MUL; + } +} + +void CompilerUtils::storeInMemory(unsigned _offset, unsigned _bytes, bool _leftAligned) +{ + if (asserts(0 < _bytes && _bytes <= 32)) + BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Memory store of 0 or more than 32 bytes requested.")); + if (_bytes != 32 && !_leftAligned) + // shift the value accordingly before storing + m_context << (u256(1) << ((32 - _bytes) * 8)) << eth::Instruction::MUL; + m_context << u256(_offset) << eth::Instruction::MSTORE; +} + void CompilerUtils::moveToStackVariable(VariableDeclaration const& _variable) { unsigned const stackPosition = m_context.baseToCurrentStackOffset(m_context.getBaseStackOffsetOfVariable(_variable)); diff --git a/libsolidity/CompilerUtils.h b/libsolidity/CompilerUtils.h index 4da533752..928f0e2d3 100644 --- a/libsolidity/CompilerUtils.h +++ b/libsolidity/CompilerUtils.h @@ -35,6 +35,18 @@ class CompilerUtils public: CompilerUtils(CompilerContext& _context): m_context(_context) {} + /// Loads data from memory to the stack. + /// @param _offset offset in memory (or calldata) + /// @param _bytes number of bytes to load + /// @param _leftAligned if true, store left aligned on stack (otherwise right aligned) + /// @param _fromCalldata if true, load from calldata, not from memory + void loadFromMemory(unsigned _offset, unsigned _bytes = 32, bool _leftAligned = false, bool _fromCalldata = false); + /// Stores data from stack in memory. + /// @param _offset offset in memory + /// @param _bytes number of bytes to store + /// @param _leftAligned if true, data is left aligned on stack (otherwise right aligned) + void storeInMemory(unsigned _offset, unsigned _bytes = 32, bool _leftAligned = false); + /// Moves the value that is at the top of the stack to a stack variable. void moveToStackVariable(VariableDeclaration const& _variable); /// Copies a variable of type @a _type from a stack depth of @a _stackDepth to the top of the stack. diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 5e688f6bd..d71d98cd6 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -225,15 +225,14 @@ bool ExpressionCompiler::visit(FunctionCall& _functionCall) BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(arguments[i]->getLocation()) << errinfo_comment("Type " + type.toString() + " not yet supported.")); - if (numBytes != 32) - if (type.getCategory() != Type::Category::STRING) - m_context << (u256(1) << ((32 - numBytes) * 8)) << eth::Instruction::MUL; - m_context << u256(dataOffset) << eth::Instruction::MSTORE; + bool const leftAligned = type.getCategory() == Type::Category::STRING; + CompilerUtils(m_context).storeInMemory(dataOffset, numBytes, leftAligned); dataOffset += numBytes; } //@todo only return the first return value for now - unsigned retSize = function.getReturnParameterTypes().empty() ? 0 - : function.getReturnParameterTypes().front()->getCalldataEncodedSize(); + Type const* firstType = function.getReturnParameterTypes().empty() ? nullptr : + function.getReturnParameterTypes().front().get(); + unsigned retSize = firstType ? firstType->getCalldataEncodedSize() : 0; // CALL arguments: outSize, outOff, inSize, inOff, value, addr, gas (stack top) m_context << u256(retSize) << u256(0) << u256(dataOffset) << u256(0) << u256(0); _functionCall.getExpression().accept(*this); // pushes addr and function index @@ -241,17 +240,10 @@ bool ExpressionCompiler::visit(FunctionCall& _functionCall) << u256(25) << eth::Instruction::GAS << eth::Instruction::SUB << eth::Instruction::CALL << eth::Instruction::POP; // @todo do not ignore failure indicator - if (retSize == 32) - m_context << u256(0) << eth::Instruction::MLOAD; - else if (retSize > 0) + if (retSize > 0) { - if (function.getReturnParameterTypes().front()->getCategory() == Type::Category::STRING) - m_context << (u256(1) << ((32 - retSize) * 8)) << eth::Instruction::DUP1 - << u256(0) << eth::Instruction::MLOAD - << eth::Instruction::DIV << eth::Instruction::MUL; - else - m_context << (u256(1) << ((32 - retSize) * 8)) - << u256(0) << eth::Instruction::MLOAD << eth::Instruction::DIV; + bool const leftAligned = firstType->getCategory() == Type::Category::STRING; + CompilerUtils(m_context).loadFromMemory(0, retSize, leftAligned); } break; } @@ -275,7 +267,8 @@ bool ExpressionCompiler::visit(FunctionCall& _functionCall) arguments.front()->accept(*this); appendTypeConversion(*arguments.front()->getType(), *function.getParameterTypes().front(), true); // @todo move this once we actually use memory - m_context << u256(0) << eth::Instruction::MSTORE << u256(32) << u256(0) << eth::Instruction::SHA3; + CompilerUtils(m_context).storeInMemory(0); + m_context << u256(32) << u256(0) << eth::Instruction::SHA3; break; case Location::ECRECOVER: case Location::SHA256: @@ -291,13 +284,13 @@ bool ExpressionCompiler::visit(FunctionCall& _functionCall) arguments[i]->accept(*this); appendTypeConversion(*arguments[i]->getType(), *function.getParameterTypes()[i], true); // @todo move this once we actually use memory - m_context << u256(i * 32) << eth::Instruction::MSTORE; + CompilerUtils(m_context).storeInMemory(i * 32); } m_context << u256(32) << u256(0) << u256(arguments.size() * 32) << u256(0) << u256(0) << contractAddress << u256(500) //@todo determine actual gas requirement << eth::Instruction::CALL - << eth::Instruction::POP - << u256(0) << eth::Instruction::MLOAD; + << eth::Instruction::POP; + CompilerUtils(m_context).loadFromMemory(0); break; } default: @@ -381,7 +374,8 @@ bool ExpressionCompiler::visit(IndexAccess& _indexAccess) *dynamic_cast(*_indexAccess.getBaseExpression().getType()).getKeyType(), true); // @todo move this once we actually use memory - m_context << u256(32) << eth::Instruction::MSTORE << u256(0) << eth::Instruction::MSTORE; + CompilerUtils(m_context).storeInMemory(0); + CompilerUtils(m_context).storeInMemory(32); m_context << u256(64) << u256(0) << eth::Instruction::SHA3; m_currentLValue = LValue(m_context, LValue::STORAGE, *_indexAccess.getType()); From 15d7d99225003456c747b4c58919bd3b979e8be0 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 11 Dec 2014 12:11:29 +0100 Subject: [PATCH 121/277] extdep minimum cmake version required set to 2.8.12 --- extdep/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index 031093f56..ea708fbe3 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) include(ExternalProject) include(CMakeParseArguments) From 37a15d96ea38401cdeddefdbfe4cfb39e7b83682 Mon Sep 17 00:00:00 2001 From: Christian Date: Thu, 11 Dec 2014 14:19:11 +0100 Subject: [PATCH 122/277] Support empty strings. --- libsolidity/AST.cpp | 2 +- libsolidity/Compiler.cpp | 4 ++-- libsolidity/CompilerUtils.cpp | 18 ++++++++++++++---- libsolidity/Token.h | 1 + libsolidity/Types.cpp | 8 ++++---- test/solidityEndToEndTest.cpp | 14 ++++++++++++++ test/solidityNameAndTypeResolution.cpp | 8 -------- 7 files changed, 36 insertions(+), 19 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 593e0960c..8174d138a 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -339,7 +339,7 @@ void Literal::checkTypeRequirements() { m_type = Type::forLiteral(*this); if (!m_type) - BOOST_THROW_EXCEPTION(createTypeError("Literal value too large or too small.")); + BOOST_THROW_EXCEPTION(createTypeError("Literal value too large.")); } } diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index 940a5e700..92d574fb1 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -135,7 +135,7 @@ unsigned Compiler::appendCalldataUnpacker(FunctionDefinition const& _function, b for (ASTPointer const& var: _function.getParameters()) { unsigned const numBytes = var->getType()->getCalldataEncodedSize(); - if (numBytes == 0 || numBytes > 32) + if (numBytes > 32) BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(var->getLocation()) << errinfo_comment("Type " + var->getType()->toString() + " not yet supported.")); @@ -156,7 +156,7 @@ void Compiler::appendReturnValuePacker(FunctionDefinition const& _function) { Type const& paramType = *parameters[i]->getType(); unsigned numBytes = paramType.getCalldataEncodedSize(); - if (numBytes == 0 || numBytes > 32) + if (numBytes > 32) BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(parameters[i]->getLocation()) << errinfo_comment("Type " + paramType.toString() + " not yet supported.")); diff --git a/libsolidity/CompilerUtils.cpp b/libsolidity/CompilerUtils.cpp index 0ee4a53cb..9f474896e 100644 --- a/libsolidity/CompilerUtils.cpp +++ b/libsolidity/CompilerUtils.cpp @@ -33,9 +33,14 @@ namespace solidity void CompilerUtils::loadFromMemory(unsigned _offset, unsigned _bytes, bool _leftAligned, bool _fromCalldata) { + if (_bytes == 0) + { + m_context << u256(0); + return; + } eth::Instruction load = _fromCalldata ? eth::Instruction::CALLDATALOAD : eth::Instruction::MLOAD; - if (asserts(0 < _bytes && _bytes <= 32)) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Memory load of 0 or more than 32 bytes requested.")); + if (asserts(_bytes <= 32)) + BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Memory load of more than 32 bytes requested.")); if (_bytes == 32) m_context << u256(_offset) << load; else @@ -53,8 +58,13 @@ void CompilerUtils::loadFromMemory(unsigned _offset, unsigned _bytes, bool _left void CompilerUtils::storeInMemory(unsigned _offset, unsigned _bytes, bool _leftAligned) { - if (asserts(0 < _bytes && _bytes <= 32)) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Memory store of 0 or more than 32 bytes requested.")); + if (_bytes == 0) + { + m_context << eth::Instruction::POP; + return; + } + if (asserts(_bytes <= 32)) + BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Memory store of more than 32 bytes requested.")); if (_bytes != 32 && !_leftAligned) // shift the value accordingly before storing m_context << (u256(1) << ((32 - _bytes) * 8)) << eth::Instruction::MUL; diff --git a/libsolidity/Token.h b/libsolidity/Token.h index f9ded3114..21b74eceb 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -269,6 +269,7 @@ namespace solidity K(ADDRESS, "address", 0) \ K(BOOL, "bool", 0) \ K(STRING_TYPE, "string", 0) \ + K(STRING0, "string0", 0) \ K(STRING1, "string1", 0) \ K(STRING2, "string2", 0) \ K(STRING3, "string3", 0) \ diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 543c27c2d..00e530c3f 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -53,8 +53,8 @@ shared_ptr Type::fromElementaryTypeName(Token::Value _typeToken) return make_shared(0, IntegerType::Modifier::ADDRESS); else if (_typeToken == Token::BOOL) return make_shared(); - else if (Token::STRING1 <= _typeToken && _typeToken <= Token::STRING32) - return make_shared(int(_typeToken) - int(Token::STRING1) + 1); + else if (Token::STRING0 <= _typeToken && _typeToken <= Token::STRING32) + return make_shared(int(_typeToken) - int(Token::STRING0)); else BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unable to convert elementary typename " + std::string(Token::toString(_typeToken)) + " to type.")); @@ -199,14 +199,14 @@ const MemberList IntegerType::AddressMemberList = shared_ptr StaticStringType::smallestTypeForLiteral(string const& _literal) { - if (0 < _literal.length() && _literal.length() <= 32) + if (_literal.length() <= 32) return make_shared(_literal.length()); return shared_ptr(); } StaticStringType::StaticStringType(int _bytes): m_bytes(_bytes) { - if (asserts(m_bytes > 0 && m_bytes <= 32)) + if (asserts(m_bytes >= 0 && m_bytes <= 32)) BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid byte number for static string type: " + dev::toString(m_bytes))); } diff --git a/test/solidityEndToEndTest.cpp b/test/solidityEndToEndTest.cpp index 940ccac63..5523ded39 100644 --- a/test/solidityEndToEndTest.cpp +++ b/test/solidityEndToEndTest.cpp @@ -510,6 +510,20 @@ BOOST_AUTO_TEST_CASE(strings) BOOST_CHECK(callContractFunction(1, bytes({0x00, 0x02, 0x01})) == expectation); } +BOOST_AUTO_TEST_CASE(empty_string_on_stack) +{ + char const* sourceCode = "contract test {\n" + " function run(string0 empty, uint8 inp) returns(uint16 a, string0 b, string4 c) {\n" + " var x = \"abc\";\n" + " var y = \"\";\n" + " var z = inp;\n" + " a = z; b = y; c = x;" + " }\n" + "}\n"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction(0, bytes({0x02})) == bytes({0x00, 0x02, 'a', 'b', 'c', 0x00})); +} + BOOST_AUTO_TEST_CASE(state_smoke_test) { char const* sourceCode = "contract test {\n" diff --git a/test/solidityNameAndTypeResolution.cpp b/test/solidityNameAndTypeResolution.cpp index 7357471cc..03eaebb3a 100644 --- a/test/solidityNameAndTypeResolution.cpp +++ b/test/solidityNameAndTypeResolution.cpp @@ -226,14 +226,6 @@ BOOST_AUTO_TEST_CASE(type_inference_explicit_conversion) BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); } -BOOST_AUTO_TEST_CASE(empty_string_literal) -{ - char const* text = "contract test {\n" - " function f() { var x = \"\"; }" - "}\n"; - BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); -} - BOOST_AUTO_TEST_CASE(large_string_literal) { char const* text = "contract test {\n" From fb72a7ce5faf4399ed6dfe5f4962c214a9483aa4 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 11 Dec 2014 15:06:11 +0100 Subject: [PATCH 123/277] fixed styling issues --- CMakeLists.txt | 8 ++--- cmake/FindGmp.cmake | 6 ++-- cmake/FindJsonRpcCpp.cmake | 27 ++++++++-------- cmake/FindLevelDB.cmake | 12 +++---- cmake/FindMiniupnpc.cmake | 6 ++-- cmake/FindReadline.cmake | 6 ++-- eth/CMakeLists.txt | 10 +++--- exp/CMakeLists.txt | 4 +-- extdep/compile/argtable2.cmake | 16 ++++----- extdep/compile/boost.cmake | 4 +-- extdep/compile/cryptopp.cmake | 52 ++++++++++++++--------------- extdep/compile/curl.cmake | 43 ++++++++++++------------ extdep/compile/icu.cmake | 20 ++++++------ extdep/compile/jom.cmake | 18 +++++------ extdep/compile/json-rpc-cpp.cmake | 54 +++++++++++++++---------------- extdep/compile/jsoncpp.cmake | 23 ++++++------- extdep/compile/leveldb.cmake | 32 +++++++++--------- extdep/compile/qt.cmake | 42 ++++++++++++------------ extdep/compile/snappy.cmake | 14 ++++---- extdep/miniupnpc.cmake | 4 +-- libethereum/CMakeLists.txt | 2 +- libethereumx/CMakeLists.txt | 31 ++++-------------- libevm/CMakeLists.txt | 7 ++-- libevmcore/CMakeLists.txt | 3 +- libjsqrc/CMakeLists.txt | 2 +- liblll/CMakeLists.txt | 1 + libp2p/CMakeLists.txt | 4 ++- libpyserpent/CMakeLists.txt | 26 ++------------- libqethereum/CMakeLists.txt | 15 ++++++--- libserpent/CMakeLists.txt | 1 + libsolidity/CMakeLists.txt | 5 +-- libweb3jsonrpc/CMakeLists.txt | 2 +- libwebthree/CMakeLists.txt | 7 ++-- libwhisper/CMakeLists.txt | 7 ++-- mix/CMakeLists.txt | 2 +- neth/CMakeLists.txt | 6 ++-- secp256k1/CMakeLists.txt | 3 +- test/CMakeLists.txt | 2 +- walleth/CMakeLists.txt | 17 +--------- 39 files changed, 251 insertions(+), 293 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a4ed1c400..21c17e9ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -146,8 +146,8 @@ if (NOT LANGUAGES) # add_subdirectory(libethereumx) # TODO remove add_subdirectory(libwebthree) - add_subdirectory(test) - add_subdirectory(eth) + add_subdirectory(test) + add_subdirectory(eth) if("x${CMAKE_BUILD_TYPE}" STREQUAL "xDebug") add_subdirectory(exp) endif () @@ -170,8 +170,8 @@ if (NOT LANGUAGES) endif () add_subdirectory(libjsqrc) - add_subdirectory(libqethereum) - add_subdirectory(alethzero) + add_subdirectory(libqethereum) + add_subdirectory(alethzero) add_subdirectory(third) add_subdirectory(mix) diff --git a/cmake/FindGmp.cmake b/cmake/FindGmp.cmake index 4d7a3a04c..dc2bce813 100644 --- a/cmake/FindGmp.cmake +++ b/cmake/FindGmp.cmake @@ -18,14 +18,14 @@ find_path( find_library( GMP_LIBRARY - NAMES gmp - DOC "gmp library" + NAMES gmp + DOC "gmp library" ) # handle the QUIETLY and REQUIRED arguments and set GMP_FOUND to TRUE # if all listed variables are TRUE, hide their existence from configuration view include(FindPackageHandleStandardArgs) find_package_handle_standard_args(gmp DEFAULT_MSG - GMP_INCLUDE_DIR GMP_LIBRARY) + GMP_INCLUDE_DIR GMP_LIBRARY) mark_as_advanced (GMP_INCLUDE_DIR GMP_LIBRARY) diff --git a/cmake/FindJsonRpcCpp.cmake b/cmake/FindJsonRpcCpp.cmake index 00da29f75..221180337 100644 --- a/cmake/FindJsonRpcCpp.cmake +++ b/cmake/FindJsonRpcCpp.cmake @@ -11,34 +11,33 @@ # only look in default directories find_path( - JSON_RPC_CPP_INCLUDE_DIR - NAMES jsonrpccpp/server.h - PATH_SUFFIXES jsonrpc - DOC "json-rpc-cpp include dir" + JSON_RPC_CPP_INCLUDE_DIR + NAMES jsonrpccpp/server.h + PATH_SUFFIXES jsonrpc + DOC "json-rpc-cpp include dir" ) find_library( - JSON_RPC_CPP_COMMON_LIBRARY - NAMES jsonrpccpp-common - DOC "json-rpc-cpp common library" + JSON_RPC_CPP_COMMON_LIBRARY + NAMES jsonrpccpp-common + DOC "json-rpc-cpp common library" ) find_library( - JSON_RPC_CPP_SERVER_LIBRARY - NAMES jsonrpccpp-server - DOC "json-rpc-cpp server library" + JSON_RPC_CPP_SERVER_LIBRARY + NAMES jsonrpccpp-server + DOC "json-rpc-cpp server library" ) find_library( - JSON_RPC_CPP_CLIENT_LIBRARY - NAMES jsonrpccpp-client - DOC "json-rpc-cpp client library" + JSON_RPC_CPP_CLIENT_LIBRARY + NAMES jsonrpccpp-client + DOC "json-rpc-cpp client library" ) # message (" - json-rcp-cpp header : ${JSON_RPC_CPP_INCLUDE_DIRS}") # message (" - json-rcp-cpp lib : ${JSON_RPC_CPP_LIBRARIES}") - # handle the QUIETLY and REQUIRED arguments and set JSON_RPC_CPP_FOUND to TRUE # if all listed variables are TRUE, hide their existence from configuration view include(FindPackageHandleStandardArgs) diff --git a/cmake/FindLevelDB.cmake b/cmake/FindLevelDB.cmake index 26629d35f..3806be9ad 100644 --- a/cmake/FindLevelDB.cmake +++ b/cmake/FindLevelDB.cmake @@ -11,15 +11,15 @@ # only look in default directories find_path( - LEVELDB_INCLUDE_DIR - NAMES leveldb/db.h + LEVELDB_INCLUDE_DIR + NAMES leveldb/db.h DOC "leveldb include dir" ) find_library( - LEVELDB_LIBRARY - NAMES leveldb - DOC "leveldb library" + LEVELDB_LIBRARY + NAMES leveldb + DOC "leveldb library" ) # message (" - leveldb header : ${LEVELDB_INCLUDE_DIR}") @@ -30,6 +30,6 @@ find_library( # if all listed variables are TRUE, hide their existence from configuration view include(FindPackageHandleStandardArgs) find_package_handle_standard_args(leveldb DEFAULT_MSG - LEVELDB_INCLUDE_DIR LEVELDB_LIBRARY) + LEVELDB_INCLUDE_DIR LEVELDB_LIBRARY) mark_as_advanced (LEVELDB_INCLUDE_DIR LEVELDB_LIBRARY) diff --git a/cmake/FindMiniupnpc.cmake b/cmake/FindMiniupnpc.cmake index 90a202dce..55795d0f9 100644 --- a/cmake/FindMiniupnpc.cmake +++ b/cmake/FindMiniupnpc.cmake @@ -18,14 +18,14 @@ find_path( find_library( MINIUPNPC_LIBRARY - NAMES miniupnpc - DOC "miniupnpc library" + NAMES miniupnpc + DOC "miniupnpc library" ) # handle the QUIETLY and REQUIRED arguments and set MINIUPNPC_FOUND to TRUE # if all listed variables are TRUE, hide their existence from configuration view include(FindPackageHandleStandardArgs) find_package_handle_standard_args(miniupnpc DEFAULT_MSG - MINIUPNPC_INCLUDE_DIR MINIUPNPC_LIBRARY) + MINIUPNPC_INCLUDE_DIR MINIUPNPC_LIBRARY) mark_as_advanced (MINIUPNPC_INCLUDE_DIR MINIUPNPC_LIBRARY) diff --git a/cmake/FindReadline.cmake b/cmake/FindReadline.cmake index 16eb483ee..3db845bd0 100644 --- a/cmake/FindReadline.cmake +++ b/cmake/FindReadline.cmake @@ -18,14 +18,14 @@ find_path( find_library( READLINE_LIBRARY - NAMES readline - DOC "readline library" + NAMES readline + DOC "readline library" ) # handle the QUIETLY and REQUIRED arguments and set READLINE_FOUND to TRUE # if all listed variables are TRUE, hide their existence from configuration view include(FindPackageHandleStandardArgs) find_package_handle_standard_args(readline DEFAULT_MSG - READLINE_INCLUDE_DIR READLINE_LIBRARY) + READLINE_INCLUDE_DIR READLINE_LIBRARY) mark_as_advanced (READLINE_INCLUDE_DIR READLINE_LIBRARY) diff --git a/eth/CMakeLists.txt b/eth/CMakeLists.txt index fe5571f60..a7feb4927 100644 --- a/eth/CMakeLists.txt +++ b/eth/CMakeLists.txt @@ -17,16 +17,16 @@ add_dependencies(${EXECUTABLE} BuildInfo.h) target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARY_RELEASE}) target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY_RELEASE}) -if(MINIUPNPC_FOUND) +if (MINIUPNPC_FOUND) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) endif() -if(JSON_RPC_CPP_FOUND) - target_link_libraries(${EXECUTABLE} web3jsonrpc) +if (READLINE_FOUND) + target_link_libraries(${EXECUTABLE} ${READLINE_LIBRARY}) endif() -if (READLINE_FOUND) -target_link_libraries(${EXECUTABLE} ${READLINE_LIBRARY}) +if (JSONRPC) + target_link_libraries(${EXECUTABLE} web3jsonrpc) endif() target_link_libraries(${EXECUTABLE} webthree) diff --git a/exp/CMakeLists.txt b/exp/CMakeLists.txt index 1cd5218e2..47db2afe7 100644 --- a/exp/CMakeLists.txt +++ b/exp/CMakeLists.txt @@ -12,8 +12,8 @@ add_executable(${EXECUTABLE} ${SRC_LIST}) target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) -if(MINIUPNPC_FOUND) -target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) +if (MINIUPNPC_FOUND) + target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) endif() target_link_libraries(${EXECUTABLE} ethereum) diff --git a/extdep/compile/argtable2.cmake b/extdep/compile/argtable2.cmake index 88063a40f..778d6a299 100644 --- a/extdep/compile/argtable2.cmake +++ b/extdep/compile/argtable2.cmake @@ -1,13 +1,13 @@ -if(APPLE) +if (APPLE) -elseif(WIN32) +elseif (WIN32) ExternalProject_Add(argtable2 - GIT_REPOSITORY https://github.com/debris/argtable.git - GIT_TAG master - BINARY_DIR argtable2-prefix/src/argtable2 - CONFIGURE_COMMAND cmake . - BUILD_COMMAND devenv argtable2.sln /build release - INSTALL_COMMAND cmd /c cp src/Release/argtable2.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp src/argtable2.h ${ETH_DEPENDENCY_INSTALL_DIR}/include + GIT_REPOSITORY https://github.com/debris/argtable.git + GIT_TAG master + BINARY_DIR argtable2-prefix/src/argtable2 + CONFIGURE_COMMAND cmake . + BUILD_COMMAND devenv argtable2.sln /build release + INSTALL_COMMAND cmd /c cp src/Release/argtable2.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp src/argtable2.h ${ETH_DEPENDENCY_INSTALL_DIR}/include ) else() endif() diff --git a/extdep/compile/boost.cmake b/extdep/compile/boost.cmake index f38c70f02..7449cf47b 100644 --- a/extdep/compile/boost.cmake +++ b/extdep/compile/boost.cmake @@ -1,6 +1,6 @@ -if(APPLE) +if (APPLE) -elseif(WIN32) +elseif (WIN32) set(boost_address_model) # on windows 64: # set(boost_address_model address-model=64) diff --git a/extdep/compile/cryptopp.cmake b/extdep/compile/cryptopp.cmake index 9f54244bc..a7e65d6c6 100644 --- a/extdep/compile/cryptopp.cmake +++ b/extdep/compile/cryptopp.cmake @@ -1,33 +1,33 @@ # CryptoPP does not have good cross-platform support, there exist several different other projects to make it work ... # TODO the OS X build throws a lot of warnings, but compiles fine -if(APPLE) - ExternalProject_Add(cryptopp - URL https://downloads.sourceforge.net/project/cryptopp/cryptopp/5.6.2/cryptopp562.zip - BINARY_DIR cryptopp-prefix/src/cryptopp - CONFIGURE_COMMAND "" - BUILD_COMMAND make CXX=clang++ CXXFLAGS=-DCRYPTOPP_DISABLE_ASM - INSTALL_COMMAND make install PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} - ) -elseif(WIN32) - file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include/cryptopp) +if (APPLE) + ExternalProject_Add(cryptopp + URL https://downloads.sourceforge.net/project/cryptopp/cryptopp/5.6.2/cryptopp562.zip + BINARY_DIR cryptopp-prefix/src/cryptopp + CONFIGURE_COMMAND "" + BUILD_COMMAND make CXX=clang++ CXXFLAGS=-DCRYPTOPP_DISABLE_ASM + INSTALL_COMMAND make install PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} + ) +elseif (WIN32) + file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include/cryptopp) - ExternalProject_Add(cryptopp - SVN_REPOSITORY http://svn.code.sf.net/p/cryptopp/code/trunk/c5 - SVN_REVISION -r "541" - BINARY_DIR cryptopp-prefix/src/cryptopp - CONFIGURE_COMMAND devenv cryptest.sln /upgrade - BUILD_COMMAND devenv cryptest.sln /build release - INSTALL_COMMAND cmd /c cp Win32/DLL_Output/Release/cryptopp.dll ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp Win32/DLL_Output/Release/cryptopp.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp *.h ${ETH_DEPENDENCY_INSTALL_DIR}/include/cryptopp - ) + ExternalProject_Add(cryptopp + SVN_REPOSITORY http://svn.code.sf.net/p/cryptopp/code/trunk/c5 + SVN_REVISION -r "541" + BINARY_DIR cryptopp-prefix/src/cryptopp + CONFIGURE_COMMAND devenv cryptest.sln /upgrade + BUILD_COMMAND devenv cryptest.sln /build release + INSTALL_COMMAND cmd /c cp Win32/DLL_Output/Release/cryptopp.dll ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp Win32/DLL_Output/Release/cryptopp.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp *.h ${ETH_DEPENDENCY_INSTALL_DIR}/include/cryptopp + ) # on Linux, the default Makefile does not work. else() - ExternalProject_Add(cryptopp - URL https://github.com/mmoss/cryptopp/archive/v5.6.2.zip - BINARY_DIR cryptopp-prefix/src/cryptopp - CONFIGURE_COMMAND "" - BUILD_COMMAND scons --shared --prefix=${ETH_DEPENDENCY_INSTALL_DIR} - INSTALL_COMMAND "" - ) + ExternalProject_Add(cryptopp + URL https://github.com/mmoss/cryptopp/archive/v5.6.2.zip + BINARY_DIR cryptopp-prefix/src/cryptopp + CONFIGURE_COMMAND "" + BUILD_COMMAND scons --shared --prefix=${ETH_DEPENDENCY_INSTALL_DIR} + INSTALL_COMMAND "" + ) endif() - + diff --git a/extdep/compile/curl.cmake b/extdep/compile/curl.cmake index d4963c1d5..64f253d43 100644 --- a/extdep/compile/curl.cmake +++ b/extdep/compile/curl.cmake @@ -1,30 +1,29 @@ -if(APPLE) -ExternalProject_Add(curl - URL http://curl.haxx.se/download/curl-7.38.0.tar.bz2 - BINARY_DIR curl-prefix/src/curl - CONFIGURE_COMMAND ./configure --with-darwinssl --prefix=${ETH_DEPENDENCY_INSTALL_DIR} --exec-prefix=${ETH_DEPENDENCY_INSTALL_DIR} - BUILD_COMMAND make -j 3 - INSTALL_COMMAND make install +if (APPLE) + ExternalProject_Add(curl + URL http://curl.haxx.se/download/curl-7.38.0.tar.bz2 + BINARY_DIR curl-prefix/src/curl + CONFIGURE_COMMAND ./configure --with-darwinssl --prefix=${ETH_DEPENDENCY_INSTALL_DIR} --exec-prefix=${ETH_DEPENDENCY_INSTALL_DIR} + BUILD_COMMAND make -j 3 + INSTALL_COMMAND make install ) -elseif(WIN32) -ExternalProject_Add(curl - GIT_REPOSITORY https://github.com/debris/libcurl-7.29 - GIT_TAG master - BINARY_DIR curl-prefix/src/curl - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND cmd /c cp lib/release/libcurl.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R include/curl ${ETH_DEPENDENCY_INSTALL_DIR}/include +elseif (WIN32) + ExternalProject_Add(curl + GIT_REPOSITORY https://github.com/debris/libcurl-7.29 + GIT_TAG master + BINARY_DIR curl-prefix/src/curl + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND cmd /c cp lib/release/libcurl.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R include/curl ${ETH_DEPENDENCY_INSTALL_DIR}/include ) else() -ExternalProject_Add(curl - URL http://curl.haxx.se/download/curl-7.38.0.tar.bz2 - BINARY_DIR curl-prefix/src/curl - CONFIGURE_COMMAND CONFIG_CMD ./configure --prefix=${ETH_DEPENDENCY_INSTALL_DIR} --exec-prefix=${ETH_DEPENDENCY_INSTALL_DIR} - BUILD_COMMAND make -j 3 - INSTALL_COMMAND make install + ExternalProject_Add(curl + URL http://curl.haxx.se/download/curl-7.38.0.tar.bz2 + BINARY_DIR curl-prefix/src/curl + CONFIGURE_COMMAND CONFIG_CMD ./configure --prefix=${ETH_DEPENDENCY_INSTALL_DIR} --exec-prefix=${ETH_DEPENDENCY_INSTALL_DIR} + BUILD_COMMAND make -j 3 + INSTALL_COMMAND make install ) endif() - diff --git a/extdep/compile/icu.cmake b/extdep/compile/icu.cmake index c0c4d46fc..ba3f3a9f0 100644 --- a/extdep/compile/icu.cmake +++ b/extdep/compile/icu.cmake @@ -1,15 +1,13 @@ -if(APPLE) +if (APPLE) -# patch for VS2013 and Windows Qt build -elseif(WIN32) -ExternalProject_Add(icu - GIT_REPOSITORY https://github.com/debris/icu-win32.git - GIT_TAG master - BINARY_DIR icu-prefix/src/icu - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - #INSTALL_COMMAND cmd /c cp lib/* ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R include/uni ${ETH_DEPENDENCY_INSTALL_DIR}/include && cp bin/* ${ETH_DEPENDENCY_INSTALL_DIR}/bin - INSTALL_COMMAND cmake -E copy_directory . ${ETH_DEPENDENCY_INSTALL_DIR} +elseif (WIN32) + ExternalProject_Add(icu + GIT_REPOSITORY https://github.com/debris/icu-win32.git + GIT_TAG master + BINARY_DIR icu-prefix/src/icu + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND cmake -E copy_directory . ${ETH_DEPENDENCY_INSTALL_DIR} ) else() diff --git a/extdep/compile/jom.cmake b/extdep/compile/jom.cmake index 17ae6caab..f300fb2ad 100644 --- a/extdep/compile/jom.cmake +++ b/extdep/compile/jom.cmake @@ -1,18 +1,16 @@ -if(APPLE) +if (APPLE) -elseif(WIN32) -# nmake is not working for qt on windows, do not know why -ExternalProject_Add(jom - URL http://download.qt-project.org/official_releases/jom/jom.zip - BINARY_DIR jom-prefix/src/jom - CONFIGURE_COMMAND "" - BUILD_COMMAND "" -INSTALL_COMMAND cmake -E copy jom.exe ${ETH_DEPENDENCY_INSTALL_DIR}/bin +elseif (WIN32) + ExternalProject_Add(jom + URL http://download.qt-project.org/official_releases/jom/jom.zip + BINARY_DIR jom-prefix/src/jom + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND cmake -E copy jom.exe ${ETH_DEPENDENCY_INSTALL_DIR}/bin ) else() endif() - diff --git a/extdep/compile/json-rpc-cpp.cmake b/extdep/compile/json-rpc-cpp.cmake index cb2985e58..9d56b0dac 100644 --- a/extdep/compile/json-rpc-cpp.cmake +++ b/extdep/compile/json-rpc-cpp.cmake @@ -3,37 +3,37 @@ # DO NOT CHANGE ANYTHING HERE! if(APPLE) -ExternalProject_Add(json-rpc-cpp - # DEPENDS argtable2 jsoncpp - # DEPENDS curl # re-enable later, when we build curl again - GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git - GIT_TAG v0.3.2 - BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp - CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR}/cmake -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev . - BUILD_COMMAND make -j 3 - INSTALL_COMMAND make install && ${CMAKE_CURRENT_SOURCE_DIR}/scripts/json-rpc-cpp_osx.sh . ${ETH_DEPENDENCY_INSTALL_DIR} + ExternalProject_Add(json-rpc-cpp + # DEPENDS argtable2 jsoncpp + # DEPENDS curl # re-enable later, when we build curl again + GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git + GIT_TAG v0.3.2 + BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp + CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR}/cmake -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev . + BUILD_COMMAND make -j 3 + INSTALL_COMMAND make install && ${CMAKE_CURRENT_SOURCE_DIR}/scripts/json-rpc-cpp_osx.sh . ${ETH_DEPENDENCY_INSTALL_DIR} ) -elseif(WIN32) -ExternalProject_Add(json-rpc-cpp - DEPENDS argtable2 jsoncpp curl - GIT_REPOSITORY https://github.com/debris/libjson-rpc-cpp.git - GIT_TAG windows - BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp - CONFIGURE_COMMAND cmake -DCMAKE_PREFIX_PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCURL_LIBRARIES=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libcurl.lib . - BUILD_COMMAND devenv libjson-rpc-cpp.sln /build release - INSTALL_COMMAND cmd /c cp lib/Release/* ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R src/jsonrpccpp ${ETH_DEPENDENCY_INSTALL_DIR}/include +elseif (WIN32) + ExternalProject_Add(json-rpc-cpp + DEPENDS argtable2 jsoncpp curl + GIT_REPOSITORY https://github.com/debris/libjson-rpc-cpp.git + GIT_TAG windows + BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp + CONFIGURE_COMMAND cmake -DCMAKE_PREFIX_PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCURL_LIBRARIES=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libcurl.lib . + BUILD_COMMAND devenv libjson-rpc-cpp.sln /build release + INSTALL_COMMAND cmd /c cp lib/Release/* ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R src/jsonrpccpp ${ETH_DEPENDENCY_INSTALL_DIR}/include ) else() -ExternalProject_Add(json-rpc-cpp - # DEPENDS argtable2 jsoncpp - # DEPENDS curl # re-enable later, when we build curl again - GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git - GIT_TAG v0.3.2 - BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp - CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR}/cmake -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST . - BUILD_COMMAND make -j 3 - INSTALL_COMMAND make install + ExternalProject_Add(json-rpc-cpp + # DEPENDS argtable2 jsoncpp + # DEPENDS curl # re-enable later, when we build curl again + GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git + GIT_TAG v0.3.2 + BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp + CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR}/cmake -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST . + BUILD_COMMAND make -j 3 + INSTALL_COMMAND make install ) endif() diff --git a/extdep/compile/jsoncpp.cmake b/extdep/compile/jsoncpp.cmake index b3bdef5e2..c0d6c97cd 100644 --- a/extdep/compile/jsoncpp.cmake +++ b/extdep/compile/jsoncpp.cmake @@ -1,15 +1,16 @@ -if(APPLE) +if (APPLE) -elseif(WIN32) +elseif (WIN32) + + file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include/jsoncpp) + ExternalProject_Add(jsoncpp + GIT_REPOSITORY https://github.com/open-source-parsers/jsoncpp + GIT_TAG svn-import + BINARY_DIR jsoncpp-prefix/src/jsoncpp + CONFIGURE_COMMAND cmake . + BUILD_COMMAND devenv jsoncpp.sln /build release + INSTALL_COMMAND cmd /c cp lib/Release/jsoncpp.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R include/json ${ETH_DEPENDENCY_INSTALL_DIR}/include/jsoncpp + ) -file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include/jsoncpp) -ExternalProject_Add(jsoncpp - GIT_REPOSITORY https://github.com/open-source-parsers/jsoncpp - GIT_TAG svn-import - BINARY_DIR jsoncpp-prefix/src/jsoncpp - CONFIGURE_COMMAND cmake . - BUILD_COMMAND devenv jsoncpp.sln /build release - INSTALL_COMMAND cmd /c cp lib/Release/jsoncpp.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R include/json ${ETH_DEPENDENCY_INSTALL_DIR}/include/jsoncpp -) else() endif() diff --git a/extdep/compile/leveldb.cmake b/extdep/compile/leveldb.cmake index 9774c8c57..2f5388c14 100644 --- a/extdep/compile/leveldb.cmake +++ b/extdep/compile/leveldb.cmake @@ -1,21 +1,21 @@ if (APPLE) -ExternalProject_Add(leveldb - #DEPENDS snappy - URL https://leveldb.googlecode.com/files/leveldb-1.15.0.tar.gz - BINARY_DIR leveldb-prefix/src/leveldb - #CONFIGURE_COMMAND patch < ${CMAKE_CURRENT_SOURCE_DIR}/compile/leveldb_osx.patch - CONFIGURE_COMMAND "" - BUILD_COMMAND export ETH_DEPENDENCY_INSTALL_DIR=${ETH_DEPENDENCY_INSTALL_DIR} && make -j 3 - INSTALL_COMMAND cp -rf include/leveldb ${ETH_DEPENDENCY_INSTALL_DIR}/include/ && cp libleveldb.a ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp libleveldb.dylib.1.15 ${ETH_DEPENDENCY_INSTALL_DIR}/lib/libleveldb.dylib + ExternalProject_Add(leveldb + #DEPENDS snappy + URL https://leveldb.googlecode.com/files/leveldb-1.15.0.tar.gz + BINARY_DIR leveldb-prefix/src/leveldb + #CONFIGURE_COMMAND patch < ${CMAKE_CURRENT_SOURCE_DIR}/compile/leveldb_osx.patch + CONFIGURE_COMMAND "" + BUILD_COMMAND export ETH_DEPENDENCY_INSTALL_DIR=${ETH_DEPENDENCY_INSTALL_DIR} && make -j 3 + INSTALL_COMMAND cp -rf include/leveldb ${ETH_DEPENDENCY_INSTALL_DIR}/include/ && cp libleveldb.a ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp libleveldb.dylib.1.15 ${ETH_DEPENDENCY_INSTALL_DIR}/lib/libleveldb.dylib ) -elseif(WIN32) -ExternalProject_Add(leveldb - GIT_REPOSITORY https://github.com/debris/leveldb-win32.git - GIT_TAG master - BINARY_DIR leveldb-prefix/src/leveldb - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND cmd /c cp lib/LibLevelDB.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib/leveldb.lib && cp -R include/leveldb ${ETH_DEPENDENCY_INSTALL_DIR}/include +elseif (WIN32) + ExternalProject_Add(leveldb + GIT_REPOSITORY https://github.com/debris/leveldb-win32.git + GIT_TAG master + BINARY_DIR leveldb-prefix/src/leveldb + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND cmd /c cp lib/LibLevelDB.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib/leveldb.lib && cp -R include/leveldb ${ETH_DEPENDENCY_INSTALL_DIR}/include ) else() diff --git a/extdep/compile/qt.cmake b/extdep/compile/qt.cmake index 049b3ba94..5fb8a1440 100644 --- a/extdep/compile/qt.cmake +++ b/extdep/compile/qt.cmake @@ -1,28 +1,28 @@ -if(APPLE) -ExternalProject_add(qt - URL http://qtmirror.ics.com/pub/qtproject/official_releases/qt/5.3/5.3.2/single/qt-everywhere-opensource-src-5.3.2.tar.gz - BINARY_DIR qt-prefix/src/qt - PATCH_COMMAND patch -d qtmultimedia/src/plugins/avfoundation/mediaplayer < ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_osx.patch - CONFIGURE_COMMAND ./configure -prefix ${ETH_DEPENDENCY_INSTALL_DIR} -system-zlib -qt-libpng -qt-libjpeg -confirm-license -opensource -nomake tests -release -nomake examples -no-xcb -arch x86_64 - BUILD_COMMAND make - INSTALL_COMMAND make install +if (APPLE) + ExternalProject_add(qt + URL http://qtmirror.ics.com/pub/qtproject/official_releases/qt/5.3/5.3.2/single/qt-everywhere-opensource-src-5.3.2.tar.gz + BINARY_DIR qt-prefix/src/qt + PATCH_COMMAND patch -d qtmultimedia/src/plugins/avfoundation/mediaplayer < ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_osx.patch + CONFIGURE_COMMAND ./configure -prefix ${ETH_DEPENDENCY_INSTALL_DIR} -system-zlib -qt-libpng -qt-libjpeg -confirm-license -opensource -nomake tests -release -nomake examples -no-xcb -arch x86_64 + BUILD_COMMAND make + INSTALL_COMMAND make install ) elseif(WIN32) -ExternalProject_Add(qt - DEPENDS icu jom - URL http://qtmirror.ics.com/pub/qtproject/official_releases/qt/5.3/5.3.2/single/qt-everywhere-opensource-src-5.3.2.tar.gz - BINARY_DIR qt-prefix/src/qt - UPDATE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_tools.bat - #PATCH_COMMAND cmake -E copy ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_configure.bat qtbase/configure.bat - CONFIGURE_COMMAND configure -prefix ${ETH_DEPENDENCY_INSTALL_DIR} -opensource -confirm-license -release -opengl desktop -platform win32-msvc2013 -icu -I ${ETH_DEPENDENCY_INSTALL_DIR}/include -L ${ETH_DEPENDENCY_INSTALL_DIR}/lib -nomake tests -nomake examples - BUILD_COMMAND nmake - INSTALL_COMMAND nmake install + ExternalProject_Add(qt + DEPENDS icu jom + URL http://qtmirror.ics.com/pub/qtproject/official_releases/qt/5.3/5.3.2/single/qt-everywhere-opensource-src-5.3.2.tar.gz + BINARY_DIR qt-prefix/src/qt + UPDATE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_tools.bat + #PATCH_COMMAND cmake -E copy ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_configure.bat qtbase/configure.bat + CONFIGURE_COMMAND configure -prefix ${ETH_DEPENDENCY_INSTALL_DIR} -opensource -confirm-license -release -opengl desktop -platform win32-msvc2013 -icu -I ${ETH_DEPENDENCY_INSTALL_DIR}/include -L ${ETH_DEPENDENCY_INSTALL_DIR}/lib -nomake tests -nomake examples + BUILD_COMMAND nmake + INSTALL_COMMAND nmake install ) -ExternalProject_Add_Step(qt configure_paths - COMMAND set PATH=${ETH_DEPENDENCY_INSTALL_DIR}/bin;%cd%/gnuwin32/bin;%cd%/qtbase/bin;%PATH% - DEPENDEES patch - DEPENDERS configure + ExternalProject_Add_Step(qt configure_paths + COMMAND set PATH=${ETH_DEPENDENCY_INSTALL_DIR}/bin;%cd%/gnuwin32/bin;%cd%/qtbase/bin;%PATH% + DEPENDEES patch + DEPENDERS configure ) else() diff --git a/extdep/compile/snappy.cmake b/extdep/compile/snappy.cmake index a15418304..0f7ba300e 100644 --- a/extdep/compile/snappy.cmake +++ b/extdep/compile/snappy.cmake @@ -1,10 +1,10 @@ -if(APPLE) -ExternalProject_Add(snappy - URL https://snappy.googlecode.com/files/snappy-1.1.1.tar.gz - BINARY_DIR snappy-prefix/src/snappy - CONFIGURE_COMMAND ./configure --disable-dependency-tracking --prefix=${ETH_DEPENDENCY_INSTALL_DIR} - BUILD_COMMAND "" - INSTALL_COMMAND make install +if (APPLE) + ExternalProject_Add(snappy + URL https://snappy.googlecode.com/files/snappy-1.1.1.tar.gz + BINARY_DIR snappy-prefix/src/snappy + CONFIGURE_COMMAND ./configure --disable-dependency-tracking --prefix=${ETH_DEPENDENCY_INSTALL_DIR} + BUILD_COMMAND "" + INSTALL_COMMAND make install ) elseif(WIN32) diff --git a/extdep/miniupnpc.cmake b/extdep/miniupnpc.cmake index b690ec2f2..4fbed6807 100644 --- a/extdep/miniupnpc.cmake +++ b/extdep/miniupnpc.cmake @@ -1,3 +1,4 @@ +# TODO this file is not used yet, but will be in future include(ExternalProject) ExternalProject_Add(miniupnpc @@ -6,6 +7,5 @@ ExternalProject_Add(miniupnpc CONFIGURE_COMMAND "" BUILD_COMMAND make -j 3 INSTALL_COMMAND make install INSTALLPREFIX=${ETH_DEPENDENCY_INSTALL_DIR} - ) - +) diff --git a/libethereum/CMakeLists.txt b/libethereum/CMakeLists.txt index 02cb8f96d..e1bad4426 100644 --- a/libethereum/CMakeLists.txt +++ b/libethereum/CMakeLists.txt @@ -28,7 +28,7 @@ target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARY_RELEASE}) if (MINIUPNPC_FOUND) -target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) + target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) endif() target_link_libraries(${EXECUTABLE} evm) diff --git a/libethereumx/CMakeLists.txt b/libethereumx/CMakeLists.txt index 1063f7981..4a3cdcda7 100644 --- a/libethereumx/CMakeLists.txt +++ b/libethereumx/CMakeLists.txt @@ -8,20 +8,19 @@ include_directories(..) set(EXECUTABLE ethereumx) -if(ETH_STATIC) - add_library(${EXECUTABLE} STATIC ${SRC_LIST}) -else() - add_library(${EXECUTABLE} SHARED ${SRC_LIST}) -endif() - file(GLOB HEADERS "*.h") +if (ETH_STATIC) + add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS}) +else() + add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) +endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) if (MINIUPNPC_LS) -target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) + target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) endif() target_link_libraries(${EXECUTABLE} ethereum) @@ -29,24 +28,6 @@ target_link_libraries(${EXECUTABLE} evm) target_link_libraries(${EXECUTABLE} lll) target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} secp256k1) -target_link_libraries(${EXECUTABLE} gmp) - -if (APPLE) - # Latest mavericks boost libraries only come with -mt - target_link_libraries(${EXECUTABLE} boost_system-mt) - target_link_libraries(${EXECUTABLE} boost_regex-mt) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt) - target_link_libraries(${EXECUTABLE} boost_thread-mt) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -elseif (UNIX) - target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -endif () install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/libevm/CMakeLists.txt b/libevm/CMakeLists.txt index e62501f93..57004ebbb 100644 --- a/libevm/CMakeLists.txt +++ b/libevm/CMakeLists.txt @@ -17,7 +17,8 @@ include_directories(${LEVELDB_INCLUDE_DIR}) set(EXECUTABLE evm) file(GLOB HEADERS "*.h") -if(ETH_STATIC) + +if (ETH_STATIC) add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS}) else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) @@ -25,8 +26,8 @@ endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) -if(MINIUPNPC_FOUND) -target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) +if (MINIUPNPC_FOUND) + target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) endif() target_link_libraries(${EXECUTABLE} ethcore) diff --git a/libevmcore/CMakeLists.txt b/libevmcore/CMakeLists.txt index 21dee65c2..9727ee1c9 100644 --- a/libevmcore/CMakeLists.txt +++ b/libevmcore/CMakeLists.txt @@ -17,7 +17,8 @@ include_directories(..) set(EXECUTABLE evmcore) file(GLOB HEADERS "*.h") -if(ETH_STATIC) + +if (ETH_STATIC) add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS}) else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) diff --git a/libjsqrc/CMakeLists.txt b/libjsqrc/CMakeLists.txt index 58dcb76ce..a6dbf023b 100644 --- a/libjsqrc/CMakeLists.txt +++ b/libjsqrc/CMakeLists.txt @@ -10,6 +10,6 @@ set(CMAKE_AUTOMOC OFF) qt5_add_resources(JSQRC js.qrc) add_library(jsqrc STATIC ${JSQRC}) -qt5_use_modules(jsqrc Core) +target_link_libraries(jsqrc Qt5::Core) install( TARGETS jsqrc ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) diff --git a/liblll/CMakeLists.txt b/liblll/CMakeLists.txt index 28e5cb758..fb79d5873 100644 --- a/liblll/CMakeLists.txt +++ b/liblll/CMakeLists.txt @@ -17,6 +17,7 @@ include_directories(..) set(EXECUTABLE lll) file(GLOB HEADERS "*.h") + if(ETH_STATIC) add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS}) else() diff --git a/libp2p/CMakeLists.txt b/libp2p/CMakeLists.txt index 8c5d49da0..f542afd0f 100644 --- a/libp2p/CMakeLists.txt +++ b/libp2p/CMakeLists.txt @@ -17,6 +17,7 @@ include_directories(${LEVELDB_INCLUDE_DIR}) set(EXECUTABLE p2p) file(GLOB HEADERS "*.h") + if(ETH_STATIC) add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS}) else() @@ -24,8 +25,9 @@ else() endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) + if(MINIUPNPC_FOUND) -target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) + target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) endif() target_link_libraries(${EXECUTABLE} devcrypto) diff --git a/libpyserpent/CMakeLists.txt b/libpyserpent/CMakeLists.txt index e6f32ec81..1ffa49ac0 100644 --- a/libpyserpent/CMakeLists.txt +++ b/libpyserpent/CMakeLists.txt @@ -4,11 +4,11 @@ aux_source_directory(. SRC_LIST) set(EXECUTABLE pyserpent) -# set(CMAKE_INSTALL_PREFIX ../lib) -add_library(${EXECUTABLE} SHARED ${SRC_LIST}) - file(GLOB HEADERS "*.h") +# set(CMAKE_INSTALL_PREFIX ../lib) +add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) + include_directories(..) target_link_libraries(${EXECUTABLE} serpent) @@ -17,26 +17,6 @@ target_link_libraries(${EXECUTABLE} evmcore) target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} ${PYTHON_LS}) -if("${TARGET_PLATFORM}" STREQUAL "w64") - target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) - target_link_libraries(${EXECUTABLE} iphlpapi) - target_link_libraries(${EXECUTABLE} ws2_32) - target_link_libraries(${EXECUTABLE} mswsock) - target_link_libraries(${EXECUTABLE} shlwapi) -elseif (APPLE) - # Latest mavericks boost libraries only come with -mt - target_link_libraries(${EXECUTABLE} boost_thread-mt) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -elseif (UNIX) - target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -else () - target_link_libraries(${EXECUTABLE} boost_thread) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -endif () - install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/libqethereum/CMakeLists.txt b/libqethereum/CMakeLists.txt index 9585943f0..e2c8f9a05 100644 --- a/libqethereum/CMakeLists.txt +++ b/libqethereum/CMakeLists.txt @@ -12,8 +12,8 @@ endif() set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) -include_directories(..) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) +include_directories(..) set(EXECUTABLE qethereum) @@ -25,11 +25,18 @@ else() add_library(${EXECUTABLE} SHARED ${RESOURCE_ADDED} ${SRC_LIST} ${HEADERS}) endif() -qt5_use_modules(${EXECUTABLE} Core Gui WebKit WebKitWidgets Widgets Network Quick Qml) -target_link_libraries(${EXECUTABLE} ethereum) -target_link_libraries(${EXECUTABLE} secp256k1) +target_link_libraries(${EXECUTABLE} Qt5::Core) +target_link_libraries(${EXECUTABLE} Qt5::Gui) +target_link_libraries(${EXECUTABLE} Qt5::WebKit) +target_link_libraries(${EXECUTABLE} Qt5::WebKitWidgets) +target_link_libraries(${EXECUTABLE} Qt5::Widgets) +target_link_libraries(${EXECUTABLE} Qt5::Network) +target_link_libraries(${EXECUTABLE} Qt5::Quick) +target_link_libraries(${EXECUTABLE} Qt5::Qml) target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_COMMON_LIBRARY}) target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_SERVER_LIBRARY}) +target_link_libraries(${EXECUTABLE} ethereum) +target_link_libraries(${EXECUTABLE} secp256k1) install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/libserpent/CMakeLists.txt b/libserpent/CMakeLists.txt index e28aeb032..1c5b8e147 100644 --- a/libserpent/CMakeLists.txt +++ b/libserpent/CMakeLists.txt @@ -16,6 +16,7 @@ include_directories(..) set(EXECUTABLE serpent) file(GLOB HEADERS "*.h") + if(ETH_STATIC) add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS}) else() diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index 44a7b9bb2..0a0b62bdd 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -18,15 +18,16 @@ include_directories(..) set(EXECUTABLE solidity) file(GLOB HEADERS "*.h") -if(ETH_STATIC) + +if (ETH_STATIC) add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS}) else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() +target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES}) target_link_libraries(${EXECUTABLE} evmcore) target_link_libraries(${EXECUTABLE} devcore) -target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES}) install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/libweb3jsonrpc/CMakeLists.txt b/libweb3jsonrpc/CMakeLists.txt index 3c5d589ca..74fea58b7 100644 --- a/libweb3jsonrpc/CMakeLists.txt +++ b/libweb3jsonrpc/CMakeLists.txt @@ -9,9 +9,9 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) -include_directories(..) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) include_directories(${LEVELDB_INCLUDE_DIR}) +include_directories(..) set(EXECUTABLE web3jsonrpc) diff --git a/libwebthree/CMakeLists.txt b/libwebthree/CMakeLists.txt index 20b4ee603..837ecb313 100644 --- a/libwebthree/CMakeLists.txt +++ b/libwebthree/CMakeLists.txt @@ -17,7 +17,8 @@ include_directories(..) set(EXECUTABLE webthree) file(GLOB HEADERS "*.h") -if(ETH_STATIC) + +if (ETH_STATIC) add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS}) else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) @@ -25,8 +26,8 @@ endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) -if(MINIUPNPC_FOUND) -target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) +if (MINIUPNPC_FOUND) + target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) endif() target_link_libraries(${EXECUTABLE} ethereum) diff --git a/libwhisper/CMakeLists.txt b/libwhisper/CMakeLists.txt index b0bb20b2b..8beb1b988 100644 --- a/libwhisper/CMakeLists.txt +++ b/libwhisper/CMakeLists.txt @@ -17,7 +17,8 @@ include_directories(${LEVELDB_INCLUDE_DIR}) set(EXECUTABLE whisper) file(GLOB HEADERS "*.h") -if(ETH_STATIC) + +if (ETH_STATIC) add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS}) else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) @@ -25,8 +26,8 @@ endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) -if(MINIUPNPC_FOUND) -target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) +if (MINIUPNPC_FOUND) + target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) endif() target_link_libraries(${EXECUTABLE} ethcore) diff --git a/mix/CMakeLists.txt b/mix/CMakeLists.txt index ce8099ce0..8f73c546b 100644 --- a/mix/CMakeLists.txt +++ b/mix/CMakeLists.txt @@ -31,7 +31,7 @@ if (APPLE) set(MACOSX_BUNDLE_ICON_FILE mix) include(BundleUtilities) - add_executable(${EXECUTABLE} MACOSX_BUNDLE ${SRC_LIST} ${HEADERS} ${UI_RESOURCES}) + add_executable(${EXECUTABLE} MACOSX_BUNDLE ${SRC_LIST} ${HEADERS} ${UI_RESOURCES}) set_target_properties(${EXECUTABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") SET_SOURCE_FILES_PROPERTIES(${EXECUTABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) SET_SOURCE_FILES_PROPERTIES(${MACOSX_BUNDLE_ICON_FILE}.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") diff --git a/neth/CMakeLists.txt b/neth/CMakeLists.txt index 731f1e4fc..14d710ef2 100644 --- a/neth/CMakeLists.txt +++ b/neth/CMakeLists.txt @@ -14,12 +14,12 @@ add_dependencies(${EXECUTABLE} BuildInfo.h) target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) -if(MINIUPNPC_FOUND) +if (MINIUPNPC_FOUND) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) endif() -if(JSON_RPC_CPP_FOUND) - target_link_libraries(${EXECUTABLE} web3jsonrpc) +if (JSONRPC) + target_link_libraries(${EXECUTABLE} web3jsonrpc) endif() target_link_libraries(${EXECUTABLE} webthree) diff --git a/secp256k1/CMakeLists.txt b/secp256k1/CMakeLists.txt index cc4f1b87c..747d5e1cb 100644 --- a/secp256k1/CMakeLists.txt +++ b/secp256k1/CMakeLists.txt @@ -24,7 +24,8 @@ if (APPLE OR UNIX) else() include_directories(${Boost_INCLUDE_DIRS}) - if(ETH_STATIC) + + if (ETH_STATIC) add_library(${EXECUTABLE} STATIC ${EXECUTABLE}.c) else() add_library(${EXECUTABLE} SHARED ${EXECUTABLE}.c) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3beb36643..440334964 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -20,7 +20,7 @@ target_link_libraries(testeth webthree) target_link_libraries(testeth ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE}) target_link_libraries(testeth ${CURL_LIBRARY}) -if (JSON_RPC_CPP_FOUND) +if (JSONRPC) target_link_libraries(testeth web3jsonrpc) target_link_libraries(testeth ${JSON_RPC_CPP_CLIENT_LIBRARY}) endif() diff --git a/walleth/CMakeLists.txt b/walleth/CMakeLists.txt index 26e010b97..44bf5f0f9 100644 --- a/walleth/CMakeLists.txt +++ b/walleth/CMakeLists.txt @@ -85,7 +85,7 @@ if (APPLE) install(CODE " include(BundleUtilities) set(BU_CHMOD_BUNDLE_ITEMS 1) - fixup_bundle(\"${APPS}\" \"${BUNDLELIBS}\" \"../libqethereum ../libethereum ../secp256k1\") + fixup_bundle(\"${APPS}\" \"${BUNDLELIBS}\" \"../libqethereum ../libethereum ../secp256k1\") " COMPONENT RUNTIME ) if (${ADDFRAMEWORKS}) @@ -96,22 +96,7 @@ if (APPLE) ) endif () -elseif ("${TARGET_PLATFORM}" STREQUAL "w64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-keep-inline-dllexport -static-libgcc -static-libstdc++ -static") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-s -Wl,-subsystem,windows -mthreads -L/usr/x86_64-w64-mingw32/plugins/platforms") - target_link_libraries(${EXECUTEABLE} gcc) - target_link_libraries(${EXECUTEABLE} mingw32 qtmain mswsock iphlpapi qwindows shlwapi Qt5PlatformSupport gdi32 comdlg32 oleaut32 imm32 winmm ole32 uuid ws2_32) - target_link_libraries(${EXECUTEABLE} boost_system-mt-s) - target_link_libraries(${EXECUTEABLE} boost_filesystem-mt-s) - target_link_libraries(${EXECUTEABLE} boost_thread_win32-mt-s) - target_link_libraries(${EXECUTEABLE} Qt5PlatformSupport) - set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) -elseif (UNIX) else () - target_link_libraries(${EXECUTEABLE} boost_system) - target_link_libraries(${EXECUTEABLE} boost_filesystem) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTEABLE} ${CMAKE_THREAD_LIBS_INIT}) install( TARGETS ${EXECUTEABLE} RUNTIME DESTINATION bin ) endif () From d439e65fee953ade58bb6ebcd9ba45a095c9ec6e Mon Sep 17 00:00:00 2001 From: ethdev Date: Thu, 11 Dec 2014 17:37:10 +0100 Subject: [PATCH 124/277] copying dlls to executable directory on windows --- alethzero/CMakeLists.txt | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index 0ea0ef8a6..a8d258efc 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -85,7 +85,23 @@ if (APPLE) file(REMOVE \${LINGER_RM}) endif () ") -else () - install( TARGETS ${EXECUTEABLE} RUNTIME DESTINATION bin) +elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin) + + file (GLOB DLLS ${CMAKE_DEPENDENCY_INSTALL_DIR}/bin/*.dll) + + foreach(DLL ${DLLS}) + add_custom_command(TARGET ${EXECUTABLE} POST_BUILD + COMMAND cmake -E copy ${DLL} $ + ) + endforeach() + + add_custom_command(TARGET ${EXECUTABLE} POST_BUILD + COMMAND cmake -E copy_directory + "${CMAKE_DEPENDENCY_INSTALL_DIR}/plugins/platforms" + $/platforms + ) +else() + install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin) endif () From 615438a890427f576bab5b7fcc5b3a8ec49098a1 Mon Sep 17 00:00:00 2001 From: Christian Date: Thu, 11 Dec 2014 17:35:23 +0100 Subject: [PATCH 125/277] Swap literals to the end if optimizing. --- libsolidity/Compiler.cpp | 15 ++++++++++----- libsolidity/Compiler.h | 6 ++++-- libsolidity/CompilerStack.cpp | 4 ++-- libsolidity/ExpressionCompiler.cpp | 26 ++++++++++++++++++++------ libsolidity/ExpressionCompiler.h | 7 ++++--- libsolidity/Token.h | 2 ++ test/solidityOptimizerTest.cpp | 19 +++++++++++++++++-- 7 files changed, 59 insertions(+), 20 deletions(-) diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index b094af194..d41bcffad 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -246,7 +246,7 @@ bool Compiler::visit(FunctionDefinition const& _function) bool Compiler::visit(IfStatement const& _ifStatement) { - ExpressionCompiler::compileExpression(m_context, _ifStatement.getCondition()); + compileExpression(_ifStatement.getCondition()); eth::AssemblyItem trueTag = m_context.appendConditionalJump(); if (_ifStatement.getFalseStatement()) _ifStatement.getFalseStatement()->accept(*this); @@ -265,7 +265,7 @@ bool Compiler::visit(WhileStatement const& _whileStatement) m_breakTags.push_back(loopEnd); m_context << loopStart; - ExpressionCompiler::compileExpression(m_context, _whileStatement.getCondition()); + compileExpression(_whileStatement.getCondition()); m_context << eth::Instruction::ISZERO; m_context.appendConditionalJumpTo(loopEnd); @@ -298,7 +298,7 @@ bool Compiler::visit(Return const& _return) //@todo modifications are needed to make this work with functions returning multiple values if (Expression const* expression = _return.getExpression()) { - ExpressionCompiler::compileExpression(m_context, *expression); + compileExpression(*expression); VariableDeclaration const& firstVariable = *_return.getFunctionReturnParameters().getParameters().front(); ExpressionCompiler::appendTypeConversion(m_context, *expression->getType(), *firstVariable.getType()); @@ -312,7 +312,7 @@ bool Compiler::visit(VariableDefinition const& _variableDefinition) { if (Expression const* expression = _variableDefinition.getExpression()) { - ExpressionCompiler::compileExpression(m_context, *expression); + compileExpression(*expression); ExpressionCompiler::appendTypeConversion(m_context, *expression->getType(), *_variableDefinition.getDeclaration().getType()); @@ -324,10 +324,15 @@ bool Compiler::visit(VariableDefinition const& _variableDefinition) bool Compiler::visit(ExpressionStatement const& _expressionStatement) { Expression const& expression = _expressionStatement.getExpression(); - ExpressionCompiler::compileExpression(m_context, expression); + compileExpression(expression); CompilerUtils(m_context).popStackElement(*expression.getType()); return false; } +void Compiler::compileExpression(Expression const& _expression) +{ + ExpressionCompiler::compileExpression(m_context, _expression, m_optimize); +} + } } diff --git a/libsolidity/Compiler.h b/libsolidity/Compiler.h index 4b8f02c5d..639e98410 100644 --- a/libsolidity/Compiler.h +++ b/libsolidity/Compiler.h @@ -30,10 +30,10 @@ namespace solidity { class Compiler: private ASTConstVisitor { public: - Compiler(): m_returnTag(m_context.newTag()) {} + explicit Compiler(bool _optimize = false): m_optimize(_optimize), m_returnTag(m_context.newTag()) {} void compileContract(ContractDefinition const& _contract, std::vector const& _magicGlobals); - bytes getAssembledBytecode(bool _optimize = false) { return m_context.getAssembledBytecode(_optimize); } + bytes getAssembledBytecode() { return m_context.getAssembledBytecode(m_optimize); } void streamAssembly(std::ostream& _stream) const { m_context.streamAssembly(_stream); } private: @@ -57,7 +57,9 @@ private: virtual bool visit(VariableDefinition const& _variableDefinition) override; virtual bool visit(ExpressionStatement const& _expressionStatement) override; + void compileExpression(Expression const& _expression); + bool const m_optimize; CompilerContext m_context; std::vector m_breakTags; ///< tag to jump to for a "break" statement std::vector m_continueTags; ///< tag to jump to for a "continue" statement diff --git a/libsolidity/CompilerStack.cpp b/libsolidity/CompilerStack.cpp index d46754856..7aaa79b1c 100644 --- a/libsolidity/CompilerStack.cpp +++ b/libsolidity/CompilerStack.cpp @@ -101,10 +101,10 @@ void CompilerStack::compile(bool _optimize) if (ContractDefinition* contract = dynamic_cast(node.get())) { m_globalContext->setCurrentContract(*contract); - shared_ptr compiler = make_shared(); + shared_ptr compiler = make_shared(_optimize); compiler->compileContract(*contract, m_globalContext->getMagicVariables()); Contract& compiledContract = m_contracts[contract->getName()]; - compiledContract.bytecode = compiler->getAssembledBytecode(_optimize); + compiledContract.bytecode = compiler->getAssembledBytecode(); compiledContract.compiler = move(compiler); } } diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index a0b0a54a8..a19c9cfd8 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -33,9 +33,9 @@ using namespace std; namespace dev { namespace solidity { -void ExpressionCompiler::compileExpression(CompilerContext& _context, Expression const& _expression) +void ExpressionCompiler::compileExpression(CompilerContext& _context, Expression const& _expression, bool _optimize) { - ExpressionCompiler compiler(_context); + ExpressionCompiler compiler(_context, _optimize); _expression.accept(compiler); } @@ -145,10 +145,24 @@ bool ExpressionCompiler::visit(BinaryOperation const& _binaryOperation) if (Token::isCompareOp(op) || op == Token::DIV || op == Token::MOD) cleanupNeeded = true; - rightExpression.accept(*this); - appendTypeConversion(*rightExpression.getType(), commonType, cleanupNeeded); - leftExpression.accept(*this); - appendTypeConversion(*leftExpression.getType(), commonType, cleanupNeeded); + // for commutative operators, push the literal as late as possible to allow improved optimization + //@todo this has to be extended for literal expressions + bool swap = (m_optimize && Token::isCommutativeOp(op) && dynamic_cast(&rightExpression) + && !dynamic_cast(&leftExpression)); + if (swap) + { + leftExpression.accept(*this); + appendTypeConversion(*leftExpression.getType(), commonType, cleanupNeeded); + rightExpression.accept(*this); + appendTypeConversion(*rightExpression.getType(), commonType, cleanupNeeded); + } + else + { + rightExpression.accept(*this); + appendTypeConversion(*rightExpression.getType(), commonType, cleanupNeeded); + leftExpression.accept(*this); + appendTypeConversion(*leftExpression.getType(), commonType, cleanupNeeded); + } if (Token::isCompareOp(op)) appendCompareOperatorCode(op, commonType); else diff --git a/libsolidity/ExpressionCompiler.h b/libsolidity/ExpressionCompiler.h index 41cb66763..fb4577c8c 100644 --- a/libsolidity/ExpressionCompiler.h +++ b/libsolidity/ExpressionCompiler.h @@ -45,14 +45,14 @@ class ExpressionCompiler: private ASTConstVisitor { public: /// Compile the given @a _expression into the @a _context. - static void compileExpression(CompilerContext& _context, Expression const& _expression); + static void compileExpression(CompilerContext& _context, Expression const& _expression, bool _optimize = false); /// Appends code to remove dirty higher order bits in case of an implicit promotion to a wider type. static void appendTypeConversion(CompilerContext& _context, Type const& _typeOnStack, Type const& _targetType); private: - ExpressionCompiler(CompilerContext& _compilerContext): - m_context(_compilerContext), m_currentLValue(m_context) {} + explicit ExpressionCompiler(CompilerContext& _compilerContext, bool _optimize = false): + m_optimize(_optimize), m_context(_compilerContext), m_currentLValue(m_context) {} virtual bool visit(Assignment const& _assignment) override; virtual void endVisit(UnaryOperation const& _unaryOperation) override; @@ -132,6 +132,7 @@ private: unsigned m_stackSize; }; + bool m_optimize; CompilerContext& m_context; LValue m_currentLValue; }; diff --git a/libsolidity/Token.h b/libsolidity/Token.h index f1a94af35..c748d9892 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -317,6 +317,8 @@ public: static bool isElementaryTypeName(Value tok) { return INT <= tok && tok < TYPES_END; } static bool isAssignmentOp(Value tok) { return ASSIGN <= tok && tok <= ASSIGN_MOD; } static bool isBinaryOp(Value op) { return COMMA <= op && op <= MOD; } + static bool isCommutativeOp(Value op) { return op == BIT_OR || op == BIT_XOR || op == BIT_AND || + op == ADD || op == MUL || op == EQ || op == NE; } static bool isArithmeticOp(Value op) { return ADD <= op && op <= MOD; } static bool isCompareOp(Value op) { return EQ <= op && op <= IN; } diff --git a/test/solidityOptimizerTest.cpp b/test/solidityOptimizerTest.cpp index f8d3b552c..69000a57f 100644 --- a/test/solidityOptimizerTest.cpp +++ b/test/solidityOptimizerTest.cpp @@ -48,7 +48,7 @@ public: m_optimize = true; bytes optimizedBytecode = compileAndRun(_sourceCode, _value, _contractName); int sizeDiff = nonOptimizedBytecode.size() - optimizedBytecode.size(); - BOOST_CHECK_MESSAGE(sizeDiff >= _expectedSizeDecrease, "Bytecode did only shrink by " + BOOST_CHECK_MESSAGE(sizeDiff == _expectedSizeDecrease, "Bytecode did only shrink by " + boost::lexical_cast(sizeDiff) + " bytes, expected: " + boost::lexical_cast(_expectedSizeDecrease)); m_optimizedContract = m_contractAddress; @@ -106,7 +106,7 @@ BOOST_AUTO_TEST_CASE(invariants) return (((a + (1 - 1)) ^ 0) | 0) & (uint(0) - 1); } })"; - compileBothVersions(19, sourceCode); + compileBothVersions(28, sourceCode); compareVersions(0, u256(0x12334664)); } @@ -124,6 +124,21 @@ BOOST_AUTO_TEST_CASE(unused_expressions) compareVersions(0); } +BOOST_AUTO_TEST_CASE(constant_folding_both_sides) +{ + // if constants involving the same associative and commutative operator are applied from both + // sides, the operator should be applied only once, because the expression compiler + // (even in non-optimized mode) pushes literals as late as possible + char const* sourceCode = R"( + contract test { + function f(uint x) returns (uint y) { + return 98 ^ (7 * ((1 | (x | 1000)) * 40) ^ 102); + } + })"; + compileBothVersions(31, sourceCode); + compareVersions(0); +} + BOOST_AUTO_TEST_SUITE_END() } From 22fa12debf95a5ec0481c437ebd27c2d7f4324c0 Mon Sep 17 00:00:00 2001 From: Christian Date: Thu, 11 Dec 2014 17:34:47 +0100 Subject: [PATCH 126/277] Do not add at the end of the function selector "loop". --- libsolidity/Compiler.cpp | 4 ++-- test/solidityCompiler.cpp | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index d41bcffad..974313418 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -109,8 +109,8 @@ void Compiler::appendFunctionSelector(ContractDefinition const& _contract) callDataUnpackerEntryPoints.push_back(m_context.newTag()); m_context << eth::dupInstruction(2) << eth::dupInstruction(2) << eth::Instruction::EQ; m_context.appendConditionalJumpTo(callDataUnpackerEntryPoints.back()); - m_context << eth::dupInstruction(4) << eth::Instruction::ADD; - //@todo avoid the last ADD (or remove it in the optimizer) + if (funid < interfaceFunctions.size() - 1) + m_context << eth::dupInstruction(4) << eth::Instruction::ADD; } m_context << eth::Instruction::STOP; // function not found diff --git a/test/solidityCompiler.cpp b/test/solidityCompiler.cpp index 004740b5e..eae8f3142 100644 --- a/test/solidityCompiler.cpp +++ b/test/solidityCompiler.cpp @@ -87,7 +87,7 @@ BOOST_AUTO_TEST_CASE(smoke_test) "}\n"; bytes code = compileContract(sourceCode); - unsigned boilerplateSize = 42; + unsigned boilerplateSize = 40; bytes expectation({byte(Instruction::JUMPDEST), byte(Instruction::PUSH1), 0x0, // initialize local variable x byte(Instruction::PUSH1), 0x2, @@ -107,8 +107,8 @@ BOOST_AUTO_TEST_CASE(different_argument_numbers) "}\n"; bytes code = compileContract(sourceCode); - unsigned shift = 70; - unsigned boilerplateSize = 83; + unsigned shift = 68; + unsigned boilerplateSize = 81; bytes expectation({byte(Instruction::JUMPDEST), byte(Instruction::PUSH1), 0x0, // initialize return variable d byte(Instruction::DUP3), @@ -158,8 +158,8 @@ BOOST_AUTO_TEST_CASE(ifStatement) "}\n"; bytes code = compileContract(sourceCode); - unsigned shift = 29; - unsigned boilerplateSize = 42; + unsigned shift = 27; + unsigned boilerplateSize = 40; bytes expectation({byte(Instruction::JUMPDEST), byte(Instruction::PUSH1), 0x0, byte(Instruction::DUP1), @@ -200,8 +200,8 @@ BOOST_AUTO_TEST_CASE(loops) "}\n"; bytes code = compileContract(sourceCode); - unsigned shift = 29; - unsigned boilerplateSize = 42; + unsigned shift = 27; + unsigned boilerplateSize = 40; bytes expectation({byte(Instruction::JUMPDEST), byte(Instruction::JUMPDEST), byte(Instruction::PUSH1), 0x1, From 488db068649a60fe4a4012b0d7b187a2e0062850 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Fri, 14 Nov 2014 11:44:51 +0100 Subject: [PATCH 127/277] Test unexpected storage entries --- test/TestHelper.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index ea0bf341c..b0935d0b6 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -329,6 +329,12 @@ void checkStorage(map _expectedStore, map _resultStore, BOOST_CHECK_MESSAGE(expectedStoreValue == resultStoreValue, _expectedAddr << ": store[" << expectedStoreKey << "] = " << resultStoreValue << ", expected " << expectedStoreValue); } } + + for (auto&& resultStorePair : _resultStore) + { + if (!_expectedStore.count(resultStorePair.first)) + BOOST_ERROR("unexpected result store key " << resultStorePair.first); + } } void checkLog(LogEntries _resultLogs, LogEntries _expectedLogs) From 79e9becdaa07c5cf6d0da35be6263a8e60d83fd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Thu, 11 Dec 2014 19:33:49 +0100 Subject: [PATCH 128/277] Report wrong account address in case of unexpected storege key --- test/TestHelper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index b0935d0b6..566c3c53f 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -333,7 +333,7 @@ void checkStorage(map _expectedStore, map _resultStore, for (auto&& resultStorePair : _resultStore) { if (!_expectedStore.count(resultStorePair.first)) - BOOST_ERROR("unexpected result store key " << resultStorePair.first); + BOOST_ERROR(_expectedAddr << ": unexpected store key " << resultStorePair.first); } } From a749a38246400c74c3cb26803b3c78339abec9ed Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 11 Dec 2014 19:55:43 +0100 Subject: [PATCH 129/277] EthExecutableHelper.cmake --- CMakeLists.txt | 1 + ...st.in => EthereumMacOSXBundleInfo.plist.in | 0 alethzero/CMakeLists.txt | 76 ++----------- cmake/EthDependencies.cmake | 4 +- cmake/EthExecutableHelper.cmake | 103 ++++++++++++++++++ extdep/CMakeLists.txt | 1 + mix/CMakeLists.txt | 2 +- third/CMakeLists.txt | 2 +- 8 files changed, 119 insertions(+), 70 deletions(-) rename alethzero/EthereumMacOSXBundleInfo.plist.in => EthereumMacOSXBundleInfo.plist.in (100%) create mode 100644 cmake/EthExecutableHelper.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 21c17e9ea..33f1052bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -108,6 +108,7 @@ message("-- CXXFLAGS: ${CMAKE_CXX_FLAGS}") # this must be an include, as a function it would messs up with variable scope! include(EthDependencies) +include(EthExecutableHelper) createBuildInfo() diff --git a/alethzero/EthereumMacOSXBundleInfo.plist.in b/EthereumMacOSXBundleInfo.plist.in similarity index 100% rename from alethzero/EthereumMacOSXBundleInfo.plist.in rename to EthereumMacOSXBundleInfo.plist.in diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index a8d258efc..b72491984 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -3,43 +3,29 @@ cmake_policy(SET CMP0015 NEW) cmake_policy(SET CMP0020 NEW) # this policy was introduced in cmake 3.0 # remove if, once 3.0 will be used on unix -if (APPLE) +if (${CMAKE_MAJOR_VERSION} GREATER 2) cmake_policy(SET CMP0043 OLD) endif() set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) -include_directories(..) + include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) +include_directories(..) qt5_wrap_ui(ui_Main.h Main.ui) -# Set name of binary and add_executable() file(GLOB HEADERS "*.h") + if (APPLE) set(EXECUTABLE AlethZero) - set(BIN_INSTALL_DIR ".") - set(DOC_INSTALL_DIR ".") - - set(PROJECT_VERSION "${ETH_VERSION}") - set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_NAME} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}") - set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}") - set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}") - set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTABLE}) - set(MACOSX_BUNDLE_ICON_FILE alethzero) - include(BundleUtilities) - - add_executable(${EXECUTABLE} MACOSX_BUNDLE alethzero.icns Main.ui ${SRC_LIST} ${HEADERS}) - set_target_properties(${EXECUTABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") - SET_SOURCE_FILES_PROPERTIES(${EXECUTABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) - SET_SOURCE_FILES_PROPERTIES(${MACOSX_BUNDLE_ICON_FILE}.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") else () set(EXECUTABLE alethzero) - add_executable(${EXECUTABLE} Main.ui ${SRC_LIST} ${HEADERS}) endif () + +# eth_add_executable is defined in cmake/EthExecutableHelper.cmake +# including SRC_LIST && HEADERS is implicit +eth_add_executable(${EXECUTABLE} ICON alethzero) add_dependencies(${EXECUTABLE} BuildInfo.h) @@ -60,48 +46,6 @@ target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} web3jsonrpc) target_link_libraries(${EXECUTABLE} jsqrc) -if (APPLE) - # First have qt5 install plugins and frameworks - # replace CMAKE_PREFIX_PATH with QT_PATH ? - add_custom_command(TARGET ${EXECUTABLE} POST_BUILD - COMMAND ${CMAKE_DEPENDENCY_INSTALL_DIR}/bin/macdeployqt ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app - WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) - - # This tool and next will inspect linked libraries in order to determine which dependencies are required - if (${CMAKE_CFG_INTDIR} STREQUAL ".") - set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE}.app") - else () - set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/\$ENV{CONFIGURATION}/${EXECUTABLE}.app") - endif () - install(CODE " - include(BundleUtilities) - set(BU_CHMOD_BUNDLE_ITEMS 1) - fixup_bundle(\"${APP_BUNDLE_PATH}\" \"${BUNDLELIBS}\" \"../libqethereum ../libethereum ../secp256k1\") - " COMPONENT RUNTIME ) - # Cleanup duplicate libs from macdeployqt - install(CODE " - file(GLOB LINGER_RM \"${APP_BUNDLE_PATH}/Contents/Frameworks/*.dylib\") - if (LINGER_RM) - file(REMOVE \${LINGER_RM}) - endif () - ") -elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") - install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin) - - file (GLOB DLLS ${CMAKE_DEPENDENCY_INSTALL_DIR}/bin/*.dll) - - foreach(DLL ${DLLS}) - add_custom_command(TARGET ${EXECUTABLE} POST_BUILD - COMMAND cmake -E copy ${DLL} $ - ) - endforeach() - - add_custom_command(TARGET ${EXECUTABLE} POST_BUILD - COMMAND cmake -E copy_directory - "${CMAKE_DEPENDENCY_INSTALL_DIR}/plugins/platforms" - $/platforms - ) -else() - install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin) -endif () +# eth_install_executable is defined in cmake/EthExecutableHelper.cmake +eth_install_executable(${EXECUTABLE}) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 8d65bc62b..31f9420ad 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -4,8 +4,8 @@ # by defining this variable, cmake will look for dependencies first in our own repository before looking in system paths like /usr/local/ ... # this must be set to point to the same directory as $ETH_DEPENDENCY_INSTALL_DIR in /extdep directory string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name) -set (CMAKE_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install/${_system_name}") -set (CMAKE_PREFIX_PATH ${CMAKE_DEPENDENCY_INSTALL_DIR}) +set (ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install/${_system_name}") +set (CMAKE_PREFIX_PATH ${ETH_DEPENDENCY_INSTALL_DIR}) # Qt5 requires opengl # TODO use proper version of windows SDK (32 vs 64) diff --git a/cmake/EthExecutableHelper.cmake b/cmake/EthExecutableHelper.cmake new file mode 100644 index 000000000..a3196389f --- /dev/null +++ b/cmake/EthExecutableHelper.cmake @@ -0,0 +1,103 @@ +# +# this function requires the following variables to be specified: +# ETH_VERSION +# PROJECT_NAME +# PROJECT_VERSION +# PROJECT_COPYRIGHT_YEAR +# PROJECT_VENDOR +# PROJECT_DOMAIN_SECOND +# PROJECT_DOMAIN_FIRST +# SRC_LIST +# HEADERS +# +# params: +# ICON +# + +macro(eth_add_executable EXECUTABLE) + set (extra_macro_args ${ARGN}) + set (options) + set (one_value_args ICON) + set (multi_value_args) + cmake_parse_arguments (ETH_ADD_EXECUTABLE "${options}" "${one_value_args}" "${multi_value_args}" "${extra_macro_args}") + + if (APPLE) + + add_executable(${EXECUTABLE} MACOSX_BUNDLE alethzero.icns Main.ui ${SRC_LIST} ${HEADERS}) + set(PROJECT_VERSION "${ETH_VERSION}") + set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") + set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_NAME} ${PROJECT_VERSION}") + set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") + set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}") + set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}") + set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}") + set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTABLE}) + set(MACOSX_BUNDLE_ICON_FILE ${ETH_ADD_EXECUTABLE_ICON}) + set_target_properties(${EXECUTABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") + set_source_files_properties(${EXECUTABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) + set_source_files_properties(${MACOSX_BUNDLE_ICON_FILE}.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + + else () + add_executable(${EXECUTABLE} Main.ui ${SRC_LIST} ${HEADERS}) + endif() + +endmacro() + +# +# this function requires the following variables to be specified: +# ETH_DEPENDENCY_INSTALL_DIR +# + +macro(eth_install_executable EXECUTABLE) + + if (APPLE) + # First have qt5 install plugins and frameworks + add_custom_command(TARGET ${EXECUTABLE} POST_BUILD + COMMAND ${ETH_DEPENDENCY_INSTALL_DIR}/bin/macdeployqt ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app + WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) + + # This tool and next will inspect linked libraries in order to determine which dependencies are required + if (${CMAKE_CFG_INTDIR} STREQUAL ".") + set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE}.app") + else () + set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/\$ENV{CONFIGURATION}/${EXECUTABLE}.app") + endif () + + # TODO check, how fixup_bundle works and if it is required + install(CODE " + include(BundleUtilities) + set(BU_CHMOD_BUNDLE_ITEMS 1) + fixup_bundle(\"${APP_BUNDLE_PATH}\" \"${BUNDLELIBS}\" \"../libqethereum ../libethereum ../secp256k1\") + " COMPONENT RUNTIME ) + # Cleanup duplicate libs from macdeployqt + install(CODE " + file(GLOB LINGER_RM \"${APP_BUNDLE_PATH}/Contents/Frameworks/*.dylib\") + if (LINGER_RM) + file(REMOVE \${LINGER_RM}) + endif () + ") + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + + # copy all dlls to executable directory + file (GLOB DLLS ${CMAKE_DEPENDENCY_INSTALL_DIR}/bin/*.dll) + + foreach(DLL ${DLLS}) + add_custom_command(TARGET ${EXECUTABLE} POST_BUILD + COMMAND cmake -E copy ${DLL} $ + ) + endforeach() + + add_custom_command(TARGET ${EXECUTABLE} POST_BUILD + COMMAND cmake -E copy_directory + "${ETH_DEPENDENCY_INSTALL_DIR}/plugins/platforms" + $/platforms + ) + + install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin) + else() + install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin) + endif () + +endmacro() + + diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index ea708fbe3..bfba8e962 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -40,6 +40,7 @@ else() if (APPLE) eth_download(snappy OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/snappy_osx.sh) endif() + eth_download(leveldb OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/leveldb_osx.sh) eth_download(qt) eth_download(cryptopp) diff --git a/mix/CMakeLists.txt b/mix/CMakeLists.txt index 8f73c546b..e36bf3812 100644 --- a/mix/CMakeLists.txt +++ b/mix/CMakeLists.txt @@ -61,7 +61,7 @@ target_link_libraries(${EXECUTABLE} jsqrc) if (APPLE) # First have qt5 install plugins and frameworks add_custom_command(TARGET ${EXECUTABLE} POST_BUILD - COMMAND ${CMAKE_DEPENDENCY_INSTALL_DIR}/bin/macdeployqt -qmldir=${CMAKE_CURRENT_SOURCE_DIR}/qml ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app + COMMAND ${ETH_DEPENDENCY_INSTALL_DIR}/bin/macdeployqt -qmldir=${CMAKE_CURRENT_SOURCE_DIR}/qml ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) # This tool and next will inspect linked libraries in order to determine which dependencies are required diff --git a/third/CMakeLists.txt b/third/CMakeLists.txt index b28210719..9c8a9e4f0 100644 --- a/third/CMakeLists.txt +++ b/third/CMakeLists.txt @@ -61,7 +61,7 @@ target_link_libraries(${EXECUTABLE} jsqrc) if (APPLE) # First have qt5 install plugins and frameworks add_custom_command(TARGET ${EXECUTABLE} POST_BUILD - COMMAND ${CMAKE_DEPENDENCY_INSTALL_DIR}/bin/macdeployqt ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app + COMMAND ${ETH_DEPENDENCY_INSTALL_DIR}/bin/macdeployqt ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) # This tool and next will inspect linked libraries in order to determine which dependencies are required From 992abb31edacf5966f3a173134b0418a89331dea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Thu, 11 Dec 2014 20:46:05 +0100 Subject: [PATCH 130/277] Replace spaces with tabs --- test/TestHelper.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index 566c3c53f..1201cfee2 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -330,11 +330,11 @@ void checkStorage(map _expectedStore, map _resultStore, } } - for (auto&& resultStorePair : _resultStore) - { - if (!_expectedStore.count(resultStorePair.first)) - BOOST_ERROR(_expectedAddr << ": unexpected store key " << resultStorePair.first); - } + for (auto&& resultStorePair : _resultStore) + { + if (!_expectedStore.count(resultStorePair.first)) + BOOST_ERROR(_expectedAddr << ": unexpected store key " << resultStorePair.first); + } } void checkLog(LogEntries _resultLogs, LogEntries _expectedLogs) From ba242853697604299e8df2736f3e4972e756cf6e Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 11 Dec 2014 21:23:27 +0100 Subject: [PATCH 131/277] mix is using executable helper --- alethzero/CMakeLists.txt | 5 ++- cmake/EthExecutableHelper.cmake | 21 +++++++++--- mix/CMakeLists.txt | 60 +++++---------------------------- 3 files changed, 30 insertions(+), 56 deletions(-) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index b72491984..b1efb64cf 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -25,7 +25,10 @@ endif () # eth_add_executable is defined in cmake/EthExecutableHelper.cmake # including SRC_LIST && HEADERS is implicit -eth_add_executable(${EXECUTABLE} ICON alethzero) +eth_add_executable(${EXECUTABLE} + ICON alethzero + UI_RESOURCES alethzero.icns Main.ui +) add_dependencies(${EXECUTABLE} BuildInfo.h) diff --git a/cmake/EthExecutableHelper.cmake b/cmake/EthExecutableHelper.cmake index a3196389f..d63dd930e 100644 --- a/cmake/EthExecutableHelper.cmake +++ b/cmake/EthExecutableHelper.cmake @@ -18,12 +18,12 @@ macro(eth_add_executable EXECUTABLE) set (extra_macro_args ${ARGN}) set (options) set (one_value_args ICON) - set (multi_value_args) + set (multi_value_args UI_RESOURCES) cmake_parse_arguments (ETH_ADD_EXECUTABLE "${options}" "${one_value_args}" "${multi_value_args}" "${extra_macro_args}") if (APPLE) - add_executable(${EXECUTABLE} MACOSX_BUNDLE alethzero.icns Main.ui ${SRC_LIST} ${HEADERS}) + add_executable(${EXECUTABLE} MACOSX_BUNDLE ${SRC_LIST} ${HEADERS} ${ETH_ADD_EXECUTABLE_UI_RESOURCES}) set(PROJECT_VERSION "${ETH_VERSION}") set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_NAME} ${PROJECT_VERSION}") @@ -38,7 +38,7 @@ macro(eth_add_executable EXECUTABLE) set_source_files_properties(${MACOSX_BUNDLE_ICON_FILE}.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources) else () - add_executable(${EXECUTABLE} Main.ui ${SRC_LIST} ${HEADERS}) + add_executable(${EXECUTABLE} ${ETH_ADD_EXECUTABLE_UI_RESOURCES} ${SRC_LIST} ${HEADERS}) endif() endmacro() @@ -47,13 +47,26 @@ endmacro() # this function requires the following variables to be specified: # ETH_DEPENDENCY_INSTALL_DIR # +# params: +# QMLDIR +# macro(eth_install_executable EXECUTABLE) + set (extra_macro_args ${ARGN}) + set (options) + set (one_value_args QMLDIR) + set (multi_value_args) + cmake_parse_arguments (ETH_INSTALL_EXECUTABLE "${options}" "${one_value_args}" "${multi_value_args}" "${extra_macro_args}") + + if (ETH_INSTALL_EXECUTABLE_QMLDIR) + set(eth_qml_dir "-qmldir=${ETH_INSTALL_EXECUTABLE_QMLDIR}") + endif() + if (APPLE) # First have qt5 install plugins and frameworks add_custom_command(TARGET ${EXECUTABLE} POST_BUILD - COMMAND ${ETH_DEPENDENCY_INSTALL_DIR}/bin/macdeployqt ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app + COMMAND ${ETH_DEPENDENCY_INSTALL_DIR}/bin/macdeployqt ${eth_qml_dir} ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) # This tool and next will inspect linked libraries in order to determine which dependencies are required diff --git a/mix/CMakeLists.txt b/mix/CMakeLists.txt index e36bf3812..9bd1ac978 100644 --- a/mix/CMakeLists.txt +++ b/mix/CMakeLists.txt @@ -8,38 +8,20 @@ if (${CMAKE_MAJOR_VERSION} GREATER 2) endif() set(CMAKE_INCLUDE_CURRENT_DIR ON) + aux_source_directory(. SRC_LIST) include_directories(..) qt5_add_resources(UI_RESOURCES qml.qrc) -# Set name of binary and add_executable() file(GLOB HEADERS "*.h") -if (APPLE) - set(EXECUTABLE mix) - set(BIN_INSTALL_DIR ".") - set(DOC_INSTALL_DIR ".") - - set(PROJECT_VERSION "${ETH_VERSION}") - set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_NAME} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}") - set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}") - set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}") - set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTABLE}) - set(MACOSX_BUNDLE_ICON_FILE mix) - include(BundleUtilities) - add_executable(${EXECUTABLE} MACOSX_BUNDLE ${SRC_LIST} ${HEADERS} ${UI_RESOURCES}) - set_target_properties(${EXECUTABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") - SET_SOURCE_FILES_PROPERTIES(${EXECUTABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) - SET_SOURCE_FILES_PROPERTIES(${MACOSX_BUNDLE_ICON_FILE}.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") +set(EXECUTABLE mix) -else () - set(EXECUTABLE mix) - add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS} ${UI_RESOURCES}) -endif () +eth_add_executable(${EXECUTABLE} + ICON mix + UI_RESOURCES ${UI_RESOURCES} +) target_link_libraries(${EXECUTABLE} Qt5::Core) target_link_libraries(${EXECUTABLE} Qt5::Gui) @@ -58,31 +40,7 @@ target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} web3jsonrpc) target_link_libraries(${EXECUTABLE} jsqrc) -if (APPLE) - # First have qt5 install plugins and frameworks - add_custom_command(TARGET ${EXECUTABLE} POST_BUILD - COMMAND ${ETH_DEPENDENCY_INSTALL_DIR}/bin/macdeployqt -qmldir=${CMAKE_CURRENT_SOURCE_DIR}/qml ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app - WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) - - # This tool and next will inspect linked libraries in order to determine which dependencies are required - if (${CMAKE_CFG_INTDIR} STREQUAL ".") - set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE}.app") - else () - set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/\$ENV{CONFIGURATION}/${EXECUTABLE}.app") - endif () - install(CODE " - include(BundleUtilities) - set(BU_CHMOD_BUNDLE_ITEMS 1) - fixup_bundle(\"${APP_BUNDLE_PATH}\" \"${BUNDLELIBS}\" \"../libqethereum ../libethereum ../secp256k1\") - " COMPONENT RUNTIME ) - # Cleanup duplicate libs from macdeployqt - install(CODE " - file(GLOB LINGER_RM \"${APP_BUNDLE_PATH}/Contents/Frameworks/*.dylib\") - if (LINGER_RM) - file(REMOVE \${LINGER_RM}) - endif () - ") -else() - install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin) -endif () +eth_install_executable(${EXECUTABLE} + QMLDIR ${CMAKE_CURRENT_SOURCE_DIR}/qml +) From 24ff0baa0522cd18058cbd428fe9e9ab03bd92a4 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 11 Dec 2014 21:31:16 +0100 Subject: [PATCH 132/277] third is using executable helper --- alethzero/CMakeLists.txt | 1 - mix/CMakeLists.txt | 2 ++ third/CMakeLists.txt | 60 ++++++++-------------------------------- 3 files changed, 13 insertions(+), 50 deletions(-) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index b1efb64cf..c4237eaee 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -24,7 +24,6 @@ else () endif () # eth_add_executable is defined in cmake/EthExecutableHelper.cmake -# including SRC_LIST && HEADERS is implicit eth_add_executable(${EXECUTABLE} ICON alethzero UI_RESOURCES alethzero.icns Main.ui diff --git a/mix/CMakeLists.txt b/mix/CMakeLists.txt index 9bd1ac978..555f6290f 100644 --- a/mix/CMakeLists.txt +++ b/mix/CMakeLists.txt @@ -18,6 +18,7 @@ file(GLOB HEADERS "*.h") set(EXECUTABLE mix) +# eth_add_executable is defined in cmake/EthExecutableHelper.cmake eth_add_executable(${EXECUTABLE} ICON mix UI_RESOURCES ${UI_RESOURCES} @@ -40,6 +41,7 @@ target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} web3jsonrpc) target_link_libraries(${EXECUTABLE} jsqrc) +# eth_install_executable is defined in cmake/EthExecutableHelper.cmake eth_install_executable(${EXECUTABLE} QMLDIR ${CMAKE_CURRENT_SOURCE_DIR}/qml ) diff --git a/third/CMakeLists.txt b/third/CMakeLists.txt index 9c8a9e4f0..c9c95cf33 100644 --- a/third/CMakeLists.txt +++ b/third/CMakeLists.txt @@ -9,39 +9,26 @@ endif() set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) -include_directories(..) + include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) +include_directories(..) qt5_wrap_ui(ui_Main.h Main.ui) -# Set name of binary and add_executable() file(GLOB HEADERS "*.h") + if (APPLE) set(EXECUTABLE Third) - set(BIN_INSTALL_DIR ".") - set(DOC_INSTALL_DIR ".") - - set(PROJECT_VERSION "${ETH_VERSION}") - set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_NAME} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}") - set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}") - set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}") - set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTABLE}) - set(MACOSX_BUNDLE_ICON_FILE third) - include(BundleUtilities) - - add_executable(${EXECUTABLE} MACOSX_BUNDLE third.icns Main.ui ${SRC_LIST} ${HEADERS}) - set_target_properties(${EXECUTABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") - SET_SOURCE_FILES_PROPERTIES(${EXECUTABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) - SET_SOURCE_FILES_PROPERTIES(${MACOSX_BUNDLE_ICON_FILE}.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") - else () set(EXECUTABLE third) - add_executable(${EXECUTABLE} Main.ui ${SRC_LIST} ${HEADERS}) endif () +# eth_add_executable is defined in cmake/EthExecutableHelper.cmake +eth_add_executable(${EXECUTABLE} + ICON third + UI_RESOURCES third.icns Main.ui +) + add_dependencies(${EXECUTABLE} BuildInfo.h) target_link_libraries(${EXECUTABLE} Qt5::Core) @@ -58,31 +45,6 @@ target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} web3jsonrpc) target_link_libraries(${EXECUTABLE} jsqrc) -if (APPLE) - # First have qt5 install plugins and frameworks - add_custom_command(TARGET ${EXECUTABLE} POST_BUILD - COMMAND ${ETH_DEPENDENCY_INSTALL_DIR}/bin/macdeployqt ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app - WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) - - # This tool and next will inspect linked libraries in order to determine which dependencies are required - if (${CMAKE_CFG_INTDIR} STREQUAL ".") - set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE}.app") - else () - set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/\$ENV{CONFIGURATION}/${EXECUTABLE}.app") - endif () - install(CODE " - include(BundleUtilities) - set(BU_CHMOD_BUNDLE_ITEMS 1) - fixup_bundle(\"${APP_BUNDLE_PATH}\" \"${BUNDLELIBS}\" \"../libqethereum ../libethereum ../secp256k1\") - " COMPONENT RUNTIME ) - # Cleanup duplicate libs from macdeployqt - install(CODE " - file(GLOB LINGER_RM \"${APP_BUNDLE_PATH}/Contents/Frameworks/*.dylib\") - if (LINGER_RM) - file(REMOVE \${LINGER_RM}) - endif () - ") -else () - install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin) -endif () +# eth_install_executable is defined in cmake/EthExecutableHelper.cmake +eth_install_executable(${EXECUTABLE}) From 24ed9d0d16a95d616fa233cc19b40f7b85c82df9 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 11 Dec 2014 21:37:22 +0100 Subject: [PATCH 133/277] removed unused plists --- mix/EthereumMacOSXBundleInfo.plist.in | 38 ------------------------- third/EthereumMacOSXBundleInfo.plist.in | 38 ------------------------- 2 files changed, 76 deletions(-) delete mode 100644 mix/EthereumMacOSXBundleInfo.plist.in delete mode 100644 third/EthereumMacOSXBundleInfo.plist.in diff --git a/mix/EthereumMacOSXBundleInfo.plist.in b/mix/EthereumMacOSXBundleInfo.plist.in deleted file mode 100644 index 684ad7908..000000000 --- a/mix/EthereumMacOSXBundleInfo.plist.in +++ /dev/null @@ -1,38 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${MACOSX_BUNDLE_EXECUTABLE_NAME} - CFBundleGetInfoString - ${MACOSX_BUNDLE_INFO_STRING} - CFBundleIconFile - ${MACOSX_BUNDLE_ICON_FILE} - CFBundleIdentifier - ${MACOSX_BUNDLE_GUI_IDENTIFIER} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - ${MACOSX_BUNDLE_LONG_VERSION_STRING} - CFBundleName - ${MACOSX_BUNDLE_BUNDLE_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - ${MACOSX_BUNDLE_SHORT_VERSION_STRING} - CFBundleSignature - ???? - CFBundleVersion - ${MACOSX_BUNDLE_BUNDLE_VERSION} - CSResourcesFileMapped - - LSRequiresCarbon - - NSHumanReadableCopyright - ${MACOSX_BUNDLE_COPYRIGHT} - NSHighResolutionCapable - - - diff --git a/third/EthereumMacOSXBundleInfo.plist.in b/third/EthereumMacOSXBundleInfo.plist.in deleted file mode 100644 index 684ad7908..000000000 --- a/third/EthereumMacOSXBundleInfo.plist.in +++ /dev/null @@ -1,38 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${MACOSX_BUNDLE_EXECUTABLE_NAME} - CFBundleGetInfoString - ${MACOSX_BUNDLE_INFO_STRING} - CFBundleIconFile - ${MACOSX_BUNDLE_ICON_FILE} - CFBundleIdentifier - ${MACOSX_BUNDLE_GUI_IDENTIFIER} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - ${MACOSX_BUNDLE_LONG_VERSION_STRING} - CFBundleName - ${MACOSX_BUNDLE_BUNDLE_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - ${MACOSX_BUNDLE_SHORT_VERSION_STRING} - CFBundleSignature - ???? - CFBundleVersion - ${MACOSX_BUNDLE_BUNDLE_VERSION} - CSResourcesFileMapped - - LSRequiresCarbon - - NSHumanReadableCopyright - ${MACOSX_BUNDLE_COPYRIGHT} - NSHighResolutionCapable - - - From 88393195b4d9835e7b35d0705c072a2686fef07d Mon Sep 17 00:00:00 2001 From: ethdev Date: Thu, 11 Dec 2014 22:26:20 +0100 Subject: [PATCH 134/277] fixed copying dlls on windows --- cmake/EthExecutableHelper.cmake | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cmake/EthExecutableHelper.cmake b/cmake/EthExecutableHelper.cmake index d63dd930e..6c7ea4f50 100644 --- a/cmake/EthExecutableHelper.cmake +++ b/cmake/EthExecutableHelper.cmake @@ -92,11 +92,11 @@ macro(eth_install_executable EXECUTABLE) elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # copy all dlls to executable directory - file (GLOB DLLS ${CMAKE_DEPENDENCY_INSTALL_DIR}/bin/*.dll) + file (GLOB DLLS ${ETH_DEPENDENCY_INSTALL_DIR}/bin/*.dll) foreach(DLL ${DLLS}) add_custom_command(TARGET ${EXECUTABLE} POST_BUILD - COMMAND cmake -E copy ${DLL} $ + COMMAND cmake -E copy "${DLL}" "$" ) endforeach() @@ -105,8 +105,9 @@ macro(eth_install_executable EXECUTABLE) "${ETH_DEPENDENCY_INSTALL_DIR}/plugins/platforms" $/platforms ) - + install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin) + else() install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin) endif () From 3a82a664becde13342a70e37a411de59612f3b5c Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 12 Dec 2014 10:27:43 +0100 Subject: [PATCH 135/277] fixed misspelling at->and --- extdep/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extdep/CMakeLists.txt b/extdep/CMakeLists.txt index bfba8e962..19cd00f7b 100644 --- a/extdep/CMakeLists.txt +++ b/extdep/CMakeLists.txt @@ -19,7 +19,7 @@ if (ETH_COMPILE) include(compile/curl.cmake) include(compile/json-rpc-cpp.cmake) - # qt at its dependencies + # qt and its dependencies include(compile/icu.cmake) include(compile/jom.cmake) include(compile/qt.cmake) From 1099a89120976ddb40bfed9e7263871afd363130 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 12 Dec 2014 10:38:43 +0100 Subject: [PATCH 136/277] when using unrecognized compiled, show warning instead of fatal_error --- cmake/EthCompilerSettings.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index 677467bea..8cf8b51b4 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -34,6 +34,6 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") set(ETH_STATIC 1) else () - message(FATAL_ERROR "Your C++ compiler does not support C++11. You have ${CMAKE_CXX_COMPILER_ID}") + message(WARNING "Your compiler is not tested, if you run into any issues, we'd welcome any patches.") endif () From 967d54992153841b116914f481ce20a596a7eb75 Mon Sep 17 00:00:00 2001 From: ethdev Date: Fri, 12 Dec 2014 11:21:39 +0100 Subject: [PATCH 137/277] all_build is working on windows --- CMakeLists.txt | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 33f1052bb..c57d11e89 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -154,7 +154,7 @@ if (NOT LANGUAGES) endif () # TODO check msvc - if(NOT ("${TARGET_PLATFORM}" STREQUAL "w64")) + if(NOT ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")) add_subdirectory(neth) endif () @@ -164,11 +164,6 @@ if (NOT LANGUAGES) #endif() if (NOT HEADLESS) - - # TODO move that somewhere else! - if ("${TARGET_PLATFORM}" STREQUAL "w64") - cmake_policy(SET CMP0020 NEW) - endif () add_subdirectory(libjsqrc) add_subdirectory(libqethereum) From 6966da558d046fff5ef7ed3ac5537b1dc54575e4 Mon Sep 17 00:00:00 2001 From: ethdev Date: Fri, 12 Dec 2014 11:24:46 +0100 Subject: [PATCH 138/277] added todo --- cmake/EthExecutableHelper.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/EthExecutableHelper.cmake b/cmake/EthExecutableHelper.cmake index 6c7ea4f50..adda57692 100644 --- a/cmake/EthExecutableHelper.cmake +++ b/cmake/EthExecutableHelper.cmake @@ -92,6 +92,7 @@ macro(eth_install_executable EXECUTABLE) elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # copy all dlls to executable directory + # TODO improve that by copying only required dlls file (GLOB DLLS ${ETH_DEPENDENCY_INSTALL_DIR}/bin/*.dll) foreach(DLL ${DLLS}) From faf541f8aee09cd2d51ea9f7d0da8ba1662498bf Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 12 Dec 2014 12:01:32 +0100 Subject: [PATCH 139/277] renamed _DIR -> _DIRS && _LIBRARY -> _LIBRARIES according to cmake guidelines --- cmake/EthDependencies.cmake | 20 ++++++++++---------- cmake/FindGmp.cmake | 7 +++++-- cmake/FindLevelDB.cmake | 13 ++++++------- cmake/FindMiniupnpc.cmake | 7 +++++-- cmake/FindReadline.cmake | 7 +++++-- eth/CMakeLists.txt | 4 ++-- exp/CMakeLists.txt | 6 +++--- libdevcrypto/CMakeLists.txt | 8 ++++---- libethcore/CMakeLists.txt | 6 +++--- libethereum/CMakeLists.txt | 6 +++--- libevm/CMakeLists.txt | 6 +++--- libp2p/CMakeLists.txt | 6 +++--- libweb3jsonrpc/CMakeLists.txt | 6 +++--- libwebthree/CMakeLists.txt | 6 +++--- libwhisper/CMakeLists.txt | 6 +++--- neth/CMakeLists.txt | 6 +++--- secp256k1/CMakeLists.txt | 2 +- test/CMakeLists.txt | 2 +- 18 files changed, 66 insertions(+), 58 deletions(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 31f9420ad..24e5bd07d 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -24,8 +24,8 @@ message(" - CryptoPP header: ${CRYPTOPP_INCLUDE_DIRS}") message(" - CryptoPP lib : ${CRYPTOPP_LIBRARIES}") find_package (LevelDB REQUIRED) -message(" - LevelDB header: ${LEVELDB_INCLUDE_DIR}") -message(" - LevelDB lib: ${LEVELDB_LIBRARY}") +message(" - LevelDB header: ${LEVELDB_INCLUDE_DIRS}") +message(" - LevelDB lib: ${LEVELDB_LIBRARIES}") # TODO the Jsoncpp package does not yet check for correct version number find_package (Jsoncpp 0.60 REQUIRED) @@ -53,8 +53,8 @@ endif() #JSONRPC # TODO get rid of -DETH_READLINE find_package (Readline 6.3.8) if (READLINE_FOUND) - message (" - readline header: ${READLINE_INCLUDE_DIR}") - message (" - readline lib : ${READLINE_LIBRARY}") + message (" - readline header: ${READLINE_INCLUDE_DIRS}") + message (" - readline lib : ${READLINE_LIBRARIES}") add_definitions(-DETH_READLINE) endif () @@ -63,8 +63,8 @@ endif () # TODO get rid of -DMINIUPNPC find_package (Miniupnpc 1.8.2013) if (MINIUPNPC_FOUND) - message (" - miniupnpc header: ${MINIUPNPC_INCLUDE_DIR}") - message (" - miniupnpc lib : ${MINIUPNPC_LIBRARY}") + message (" - miniupnpc header: ${MINIUPNPC_INCLUDE_DIRS}") + message (" - miniupnpc lib : ${MINIUPNPC_LIBRARIES}") add_definitions(-DETH_MINIUPNPC) endif() @@ -72,15 +72,15 @@ endif() # TODO it is also not required in msvc build find_package (Gmp 6.0.0) if (GMP_FOUND) - message(" - gmp Header: ${GMP_INCLUDE_DIR}") - message(" - gmp lib : ${GMP_LIBRARY}") + message(" - gmp Header: ${GMP_INCLUDE_DIRS}") + message(" - gmp lib : ${GMP_LIBRARIES}") endif() # curl is only requried for tests # TODO specify min curl version, on windows we are currenly using 7.29 find_package (CURL) -message(" - curl header: ${CURL_INCLUDE_DIR}") -message(" - curl lib : ${CURL_LIBRARY}") +message(" - curl header: ${CURL_INCLUDE_DIRS}") +message(" - curl lib : ${CURL_LIBRARIES}") # do not compile GUI if (NOT HEADLESS) diff --git a/cmake/FindGmp.cmake b/cmake/FindGmp.cmake index dc2bce813..4dc8f48c4 100644 --- a/cmake/FindGmp.cmake +++ b/cmake/FindGmp.cmake @@ -5,8 +5,8 @@ # if you nee to add a custom library search path, do it via via CMAKE_FIND_ROOT_PATH # # This module defines -# GMP_INCLUDE_DIR, where to find header, etc. -# GMP_LIBRARY, the libraries needed to use gmp. +# GMP_INCLUDE_DIRS, where to find header, etc. +# GMP_LIBRARIES, the libraries needed to use gmp. # GMP_FOUND, If false, do not try to use gmp. # only look in default directories @@ -22,6 +22,9 @@ find_library( DOC "gmp library" ) +set(GMP_INCLUDE_DIRS ${GMP_INCLUDE_DIR}) +set(GMP_LIBRARIES ${GMP_LIBRARY}) + # handle the QUIETLY and REQUIRED arguments and set GMP_FOUND to TRUE # if all listed variables are TRUE, hide their existence from configuration view include(FindPackageHandleStandardArgs) diff --git a/cmake/FindLevelDB.cmake b/cmake/FindLevelDB.cmake index 3806be9ad..6bd373a9f 100644 --- a/cmake/FindLevelDB.cmake +++ b/cmake/FindLevelDB.cmake @@ -5,8 +5,8 @@ # if you nee to add a custom library search path, do it via via CMAKE_FIND_ROOT_PATH # # This module defines -# LEVELDB_INCLUDE_DIR, where to find header, etc. -# LEVELDB_LIBRARY, the libraries needed to use leveldb. +# LEVELDB_INCLUDE_DIRS, where to find header, etc. +# LEVELDB_LIBRARIES, the libraries needed to use leveldb. # LEVELDB_FOUND, If false, do not try to use leveldb. # only look in default directories @@ -14,17 +14,16 @@ find_path( LEVELDB_INCLUDE_DIR NAMES leveldb/db.h DOC "leveldb include dir" - ) +) find_library( LEVELDB_LIBRARY NAMES leveldb DOC "leveldb library" - ) - -# message (" - leveldb header : ${LEVELDB_INCLUDE_DIR}") -# message (" - leveldb lib : ${LEVELDB_LIBRARY}") +) +set(LEVELDB_INCLUDE_DIRS ${LEVELDB_INCLUDE_DIR}) +set(LEVELDB_LIBRARIES ${LEVELDB_LIBRARY}) # handle the QUIETLY and REQUIRED arguments and set LEVELDB_FOUND to TRUE # if all listed variables are TRUE, hide their existence from configuration view diff --git a/cmake/FindMiniupnpc.cmake b/cmake/FindMiniupnpc.cmake index 55795d0f9..4ecbb0c4a 100644 --- a/cmake/FindMiniupnpc.cmake +++ b/cmake/FindMiniupnpc.cmake @@ -5,8 +5,8 @@ # if you nee to add a custom library search path, do it via via CMAKE_FIND_ROOT_PATH # # This module defines -# MINIUPNPC_INCLUDE_DIR, where to find header, etc. -# MINIUPNPC_LIBRARY, the libraries needed to use gmp. +# MINIUPNPC_INCLUDE_DIRS, where to find header, etc. +# MINIUPNPC_LIBRARIES, the libraries needed to use gmp. # MINIUPNPC_FOUND, If false, do not try to use gmp. # only look in default directories @@ -22,6 +22,9 @@ find_library( DOC "miniupnpc library" ) +set(MINIUPNPC_INCLUDE_DIRS ${MINIUPNPC_INCLUDE_DIR}) +set(MINIUPNPC_LIBRARIES ${MINIUPNPC_LIBRARY}) + # handle the QUIETLY and REQUIRED arguments and set MINIUPNPC_FOUND to TRUE # if all listed variables are TRUE, hide their existence from configuration view include(FindPackageHandleStandardArgs) diff --git a/cmake/FindReadline.cmake b/cmake/FindReadline.cmake index 3db845bd0..1f47db4a7 100644 --- a/cmake/FindReadline.cmake +++ b/cmake/FindReadline.cmake @@ -5,8 +5,8 @@ # if you nee to add a custom library search path, do it via via CMAKE_FIND_ROOT_PATH # # This module defines -# READLINE_INCLUDE_DIR, where to find header, etc. -# READLINE_LIBRARY, the libraries needed to use readline. +# READLINE_INCLUDE_DIRS, where to find header, etc. +# READLINE_LIBRARIES, the libraries needed to use readline. # READLINE_FOUND, If false, do not try to use readline. # only look in default directories @@ -22,6 +22,9 @@ find_library( DOC "readline library" ) +set(READLINE_INCLUDE_DIRS ${READLINE_INCLUDE_DIR}) +set(READLINE_LIBRARIES ${READLINE_LIBRARY}) + # handle the QUIETLY and REQUIRED arguments and set READLINE_FOUND to TRUE # if all listed variables are TRUE, hide their existence from configuration view include(FindPackageHandleStandardArgs) diff --git a/eth/CMakeLists.txt b/eth/CMakeLists.txt index a7feb4927..9996d1170 100644 --- a/eth/CMakeLists.txt +++ b/eth/CMakeLists.txt @@ -18,11 +18,11 @@ target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARY_RELEASE}) target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY_RELEASE}) if (MINIUPNPC_FOUND) - target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) + target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARIES}) endif() if (READLINE_FOUND) - target_link_libraries(${EXECUTABLE} ${READLINE_LIBRARY}) + target_link_libraries(${EXECUTABLE} ${READLINE_LIBRARIES}) endif() if (JSONRPC) diff --git a/exp/CMakeLists.txt b/exp/CMakeLists.txt index 47db2afe7..98eae7baf 100644 --- a/exp/CMakeLists.txt +++ b/exp/CMakeLists.txt @@ -3,17 +3,17 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) -include_directories(${LEVELDB_INCLUDE_DIR}) +include_directories(${LEVELDB_INCLUDE_DIRS}) include_directories(..) set(EXECUTABLE exp) add_executable(${EXECUTABLE} ${SRC_LIST}) -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) if (MINIUPNPC_FOUND) - target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) + target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARIES}) endif() target_link_libraries(${EXECUTABLE} ethereum) diff --git a/libdevcrypto/CMakeLists.txt b/libdevcrypto/CMakeLists.txt index f5661bab1..354053483 100644 --- a/libdevcrypto/CMakeLists.txt +++ b/libdevcrypto/CMakeLists.txt @@ -9,8 +9,8 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) -include_directories(${CRYPTOPP_INCLUDE_DIR}) -include_directories(${LEVELDB_INCLUDE_DIR}) +include_directories(${CRYPTOPP_INCLUDE_DIRS}) +include_directories(${LEVELDB_INCLUDE_DIRS}) include_directories(..) set(EXECUTABLE devcrypto) @@ -23,8 +23,8 @@ else() endif() target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY_RELEASE}) -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) -target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) +target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} secp256k1) diff --git a/libethcore/CMakeLists.txt b/libethcore/CMakeLists.txt index ede6eb087..960936b3a 100644 --- a/libethcore/CMakeLists.txt +++ b/libethcore/CMakeLists.txt @@ -9,8 +9,8 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) -include_directories(${CRYPTOPP_INCLUDE_DIR}) -include_directories(${LEVELDB_INCLUDE_DIR}) +include_directories(${CRYPTOPP_INCLUDE_DIRS}) +include_directories(${LEVELDB_INCLUDE_DIRS}) include_directories(..) set(EXECUTABLE ethcore) @@ -23,7 +23,7 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} secp256k1) diff --git a/libethereum/CMakeLists.txt b/libethereum/CMakeLists.txt index e1bad4426..c13f2ba18 100644 --- a/libethereum/CMakeLists.txt +++ b/libethereum/CMakeLists.txt @@ -11,7 +11,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) -include_directories(${LEVELDB_INCLUDE_DIR}) +include_directories(${LEVELDB_INCLUDE_DIRS}) include_directories(..) set(EXECUTABLE ethereum) @@ -24,11 +24,11 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARY_RELEASE}) if (MINIUPNPC_FOUND) - target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) + target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARIES}) endif() target_link_libraries(${EXECUTABLE} evm) diff --git a/libevm/CMakeLists.txt b/libevm/CMakeLists.txt index 57004ebbb..94f7e5e79 100644 --- a/libevm/CMakeLists.txt +++ b/libevm/CMakeLists.txt @@ -12,7 +12,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) include_directories(..) -include_directories(${LEVELDB_INCLUDE_DIR}) +include_directories(${LEVELDB_INCLUDE_DIRS}) set(EXECUTABLE evm) @@ -24,10 +24,10 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) if (MINIUPNPC_FOUND) - target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) + target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARIES}) endif() target_link_libraries(${EXECUTABLE} ethcore) diff --git a/libp2p/CMakeLists.txt b/libp2p/CMakeLists.txt index f542afd0f..c94ebebbd 100644 --- a/libp2p/CMakeLists.txt +++ b/libp2p/CMakeLists.txt @@ -11,8 +11,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) +include_directories(${LEVELDB_INCLUDE_DIRS}) include_directories(..) -include_directories(${LEVELDB_INCLUDE_DIR}) set(EXECUTABLE p2p) @@ -24,10 +24,10 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) if(MINIUPNPC_FOUND) - target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) + target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARIES}) endif() target_link_libraries(${EXECUTABLE} devcrypto) diff --git a/libweb3jsonrpc/CMakeLists.txt b/libweb3jsonrpc/CMakeLists.txt index 74fea58b7..9a0771ef7 100644 --- a/libweb3jsonrpc/CMakeLists.txt +++ b/libweb3jsonrpc/CMakeLists.txt @@ -10,7 +10,7 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) -include_directories(${LEVELDB_INCLUDE_DIR}) +include_directories(${LEVELDB_INCLUDE_DIRS}) include_directories(..) set(EXECUTABLE web3jsonrpc) @@ -23,13 +23,13 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_COMMON_LIBRARY}) target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_SERVER_LIBRARY}) if (MINIUPNPC_FOUND) - target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) + target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARIES}) endif() target_link_libraries(${EXECUTABLE} webthree) diff --git a/libwebthree/CMakeLists.txt b/libwebthree/CMakeLists.txt index 837ecb313..587d81493 100644 --- a/libwebthree/CMakeLists.txt +++ b/libwebthree/CMakeLists.txt @@ -11,7 +11,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) -include_directories(${LEVELDB_INCLUDE_DIR}) +include_directories(${LEVELDB_INCLUDE_DIRS}) include_directories(..) set(EXECUTABLE webthree) @@ -24,10 +24,10 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) if (MINIUPNPC_FOUND) - target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) + target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARIES}) endif() target_link_libraries(${EXECUTABLE} ethereum) diff --git a/libwhisper/CMakeLists.txt b/libwhisper/CMakeLists.txt index 8beb1b988..f51af33b7 100644 --- a/libwhisper/CMakeLists.txt +++ b/libwhisper/CMakeLists.txt @@ -12,7 +12,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) include_directories(..) -include_directories(${LEVELDB_INCLUDE_DIR}) +include_directories(${LEVELDB_INCLUDE_DIRS}) set(EXECUTABLE whisper) @@ -24,10 +24,10 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) if (MINIUPNPC_FOUND) - target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) + target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARIES}) endif() target_link_libraries(${EXECUTABLE} ethcore) diff --git a/neth/CMakeLists.txt b/neth/CMakeLists.txt index 14d710ef2..63619fd84 100644 --- a/neth/CMakeLists.txt +++ b/neth/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_policy(SET CMP0015 NEW) aux_source_directory(. SRC_LIST) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) -include_directories(${LEVELDB_INCLUDE_DIR}) +include_directories(${LEVELDB_INCLUDE_DIRS}) include_directories(..) set(EXECUTABLE neth) @@ -12,10 +12,10 @@ add_executable(${EXECUTABLE} ${SRC_LIST}) add_dependencies(${EXECUTABLE} BuildInfo.h) -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) if (MINIUPNPC_FOUND) -target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARIES}) endif() if (JSONRPC) diff --git a/secp256k1/CMakeLists.txt b/secp256k1/CMakeLists.txt index 747d5e1cb..8dbe175d5 100644 --- a/secp256k1/CMakeLists.txt +++ b/secp256k1/CMakeLists.txt @@ -20,7 +20,7 @@ if (APPLE OR UNIX) add_library(${EXECUTABLE} SHARED ${EXECUTABLE}.c field_5x52_asm.asm) endif() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -DUSE_FIELD_GMP -DUSE_NUM_GMP -DUSE_FIELD_INV_NUM") - target_link_libraries(${EXECUTABLE} ${GMP_LIBRARY}) + target_link_libraries(${EXECUTABLE} ${GMP_LIBRARIES}) else() include_directories(${Boost_INCLUDE_DIRS}) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 440334964..73003e805 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -18,7 +18,7 @@ target_link_libraries(testeth secp256k1) target_link_libraries(testeth solidity) target_link_libraries(testeth webthree) target_link_libraries(testeth ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE}) -target_link_libraries(testeth ${CURL_LIBRARY}) +target_link_libraries(testeth ${CURL_LIBRARIES}) if (JSONRPC) target_link_libraries(testeth web3jsonrpc) From b121491080c60a9c3752f38d23af6e302ca17558 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 12 Dec 2014 12:40:59 +0100 Subject: [PATCH 140/277] removed walleth, libpyserpent, iethxi and QmlEthereum class --- CMakeLists.txt | 19 -- iethxi/CMakeLists.txt | 91 ------- iethxi/EthereumMacOSXBundleInfo.plist.in | 38 --- iethxi/Main.ui | 168 ------------- iethxi/MainWin.cpp | 59 ----- iethxi/MainWin.h | 18 -- iethxi/Resources.qrc | 5 - iethxi/Simple.qml | 9 - iethxi/main.cpp | 9 - libpyserpent/CMakeLists.txt | 22 -- libpyserpent/pyserpent.cpp | 173 ------------- libqethereum/QmlEthereum.cpp | 180 -------------- libqethereum/QmlEthereum.h | 283 --------------------- walleth/CMakeLists.txt | 102 -------- walleth/EthereumMacOSXBundleInfo.plist.in | 38 --- walleth/Main.ui | 168 ------------- walleth/MainWin.cpp | 286 ---------------------- walleth/MainWin.h | 84 ------- walleth/Resources.qrc | 5 - walleth/Simple.qml | 38 --- walleth/main.cpp | 11 - 21 files changed, 1806 deletions(-) delete mode 100644 iethxi/CMakeLists.txt delete mode 100644 iethxi/EthereumMacOSXBundleInfo.plist.in delete mode 100644 iethxi/Main.ui delete mode 100644 iethxi/MainWin.cpp delete mode 100644 iethxi/MainWin.h delete mode 100644 iethxi/Resources.qrc delete mode 100644 iethxi/Simple.qml delete mode 100644 iethxi/main.cpp delete mode 100644 libpyserpent/CMakeLists.txt delete mode 100644 libpyserpent/pyserpent.cpp delete mode 100644 libqethereum/QmlEthereum.cpp delete mode 100644 libqethereum/QmlEthereum.h delete mode 100644 walleth/CMakeLists.txt delete mode 100644 walleth/EthereumMacOSXBundleInfo.plist.in delete mode 100644 walleth/Main.ui delete mode 100644 walleth/MainWin.cpp delete mode 100644 walleth/MainWin.h delete mode 100644 walleth/Resources.qrc delete mode 100644 walleth/Simple.qml delete mode 100644 walleth/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c57d11e89..d6bf59636 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -112,14 +112,6 @@ include(EthExecutableHelper) createBuildInfo() -# TODO discuss that during PR. are we still using that? - -if(NOT APPLE) - if(PYTHON_LS) - add_subdirectory(libpyserpent) - endif() -endif() - add_subdirectory(libdevcore) add_subdirectory(libevmcore) add_subdirectory(liblll) @@ -158,11 +150,6 @@ if (NOT LANGUAGES) add_subdirectory(neth) endif () - # TODO discuss that during PR. are we still using that? - #if(QTQML) - #add_definitions(-DETH_QTQML) - #endif() - if (NOT HEADLESS) add_subdirectory(libjsqrc) @@ -170,12 +157,6 @@ if (NOT LANGUAGES) add_subdirectory(alethzero) add_subdirectory(third) add_subdirectory(mix) - - # TODO discuss that during PR. are we still using that? - #if(QTQML) - #add_subdirectory(iethxi) - #add_subdirectory(walleth) // resurect once we want to submit ourselves to QML. - #endif() endif() endif() diff --git a/iethxi/CMakeLists.txt b/iethxi/CMakeLists.txt deleted file mode 100644 index c2203a4f6..000000000 --- a/iethxi/CMakeLists.txt +++ /dev/null @@ -1,91 +0,0 @@ -cmake_policy(SET CMP0015 OLD) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) -aux_source_directory(. SRC_LIST) - -include_directories(..) -link_directories(../libethcore) -link_directories(../libethereum) -link_directories(../libqethereum) - -qt5_wrap_ui(ui_Main.h Main.ui) -qt5_add_resources(RESOURCE_ADDED Resources.qrc) - -# Set name of binary and add_executable() -if (APPLE) - set(EXECUTABLE IEthXi) - set(CMAKE_INSTALL_PREFIX ./) - set(BIN_INSTALL_DIR ".") - set(DOC_INSTALL_DIR ".") - - set(PROJECT_VERSION "${ETH_VERSION}") - set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_NAME} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}") - set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}") - set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}") - set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTABLE}) - include(BundleUtilities) - - add_executable(${EXECUTABLE} MACOSX_BUNDLE Main.ui ${RESOURCE_ADDED} ${SRC_LIST}) -else () - set(EXECUTABLE iethxi) - add_executable(${EXECUTABLE} Main.ui ${RESOURCE_ADDED} ${SRC_LIST}) -endif () - -qt5_use_modules(${EXECUTABLE} Core Gui Widgets Network Quick Qml) -target_link_libraries(${EXECUTABLE} qethereum) -target_link_libraries(${EXECUTABLE} ethereum) -target_link_libraries(${EXECUTABLE} secp256k1) - -if (APPLE) - if (${ADDFRAMEWORKS}) - set_target_properties(${EXECUTABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") - endif () - - SET_SOURCE_FILES_PROPERTIES(${EXECUTABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) - - # This is a workaround for when the build-type defaults to Debug, and when a multi-config generator like xcode is used, where the type - # will not be set but defaults to release. - set(generator_lowercase "${CMAKE_GENERATOR}") - string(TOLOWER "${CMAKE_GENERATOR}" generator_lowercase) - if ("${generator_lowercase}" STREQUAL "xcode") - # TODO: Not sure how to resolve this. Possibly \${TARGET_BUILD_DIR} - set(binary_build_dir "${CMAKE_CURRENT_BINARY_DIR}/Debug") - else () - set(binary_build_dir "${CMAKE_CURRENT_BINARY_DIR}") - endif () - - set(APPS ${binary_build_dir}/${EXECUTABLE}.app) - - # This tool and the next will automatically looked at the linked libraries in order to determine what dependencies are required. Thus, target_link_libaries only needs to add ethereum and secp256k1 (above) - install(CODE " - include(BundleUtilities) - set(BU_CHMOD_BUNDLE_ITEMS 1) - fixup_bundle(\"${APPS}\" \"${BUNDLELIBS}\" \"../libqethereum ../libethereum ../secp256k1\") - " COMPONENT RUNTIME ) - - if (${ADDFRAMEWORKS}) - add_custom_target(addframeworks ALL - COMMAND /usr/local/opt/qt5/bin/macdeployqt ${binary_build_dir}/${EXECUTABLE}.app - WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - DEPENDS ${PROJECT_NAME} - ) - endif () - -elseif ("${TARGET_PLATFORM}" STREQUAL "w64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-keep-inline-dllexport -static-libgcc -static-libstdc++ -static") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-s -Wl,-subsystem,windows -mthreads -L/usr/x86_64-w64-mingw32/plugins/platforms") - target_link_libraries(${EXECUTABLE} gcc) - target_link_libraries(${EXECUTABLE} mingw32 qtmain mswsock iphlpapi qwindows shlwapi Qt5PlatformSupport gdi32 comdlg32 oleaut32 imm32 winmm ole32 uuid ws2_32) - target_link_libraries(${EXECUTABLE} boost_system-mt-s) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) - target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) - target_link_libraries(${EXECUTABLE} Qt5PlatformSupport) - set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) -elseif (UNIX) -else () - message(ERROR "platform not supported") -endif () - diff --git a/iethxi/EthereumMacOSXBundleInfo.plist.in b/iethxi/EthereumMacOSXBundleInfo.plist.in deleted file mode 100644 index 684ad7908..000000000 --- a/iethxi/EthereumMacOSXBundleInfo.plist.in +++ /dev/null @@ -1,38 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${MACOSX_BUNDLE_EXECUTABLE_NAME} - CFBundleGetInfoString - ${MACOSX_BUNDLE_INFO_STRING} - CFBundleIconFile - ${MACOSX_BUNDLE_ICON_FILE} - CFBundleIdentifier - ${MACOSX_BUNDLE_GUI_IDENTIFIER} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - ${MACOSX_BUNDLE_LONG_VERSION_STRING} - CFBundleName - ${MACOSX_BUNDLE_BUNDLE_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - ${MACOSX_BUNDLE_SHORT_VERSION_STRING} - CFBundleSignature - ???? - CFBundleVersion - ${MACOSX_BUNDLE_BUNDLE_VERSION} - CSResourcesFileMapped - - LSRequiresCarbon - - NSHumanReadableCopyright - ${MACOSX_BUNDLE_COPYRIGHT} - NSHighResolutionCapable - - - diff --git a/iethxi/Main.ui b/iethxi/Main.ui deleted file mode 100644 index fe289ba9f..000000000 --- a/iethxi/Main.ui +++ /dev/null @@ -1,168 +0,0 @@ - - - Main - - - - 0 - 0 - 562 - 488 - - - - Walleth - - - true - - - QMainWindow::AllowNestedDocks|QMainWindow::AllowTabbedDocks|QMainWindow::VerticalTabs - - - true - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - 0 wei - - - - - - - 0 peers - - - - - - - 1 block - - - - - - - - - - - 0 - 0 - 562 - 25 - - - - - &File - - - - - - &Network - - - - - - - - T&ools - - - - - - - - &Help - - - - - - - - - - - - &Quit - - - - - true - - - true - - - Use &UPnP - - - - - &Connect to Peer... - - - - - true - - - Enable &Network - - - - - true - - - &Mine - - - - - &New Address - - - - - &About... - - - - - true - - - &Preview - - - - - - - diff --git a/iethxi/MainWin.cpp b/iethxi/MainWin.cpp deleted file mode 100644 index 2d5b57094..000000000 --- a/iethxi/MainWin.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "BuildInfo.h" -#include "MainWin.h" -#include "ui_Main.h" -using namespace std; -using namespace eth; - -Main::Main(QWidget *parent) : - QObject(parent) -{ -/* qRegisterMetaType("eth::u256"); - qRegisterMetaType("eth::KeyPair"); - qRegisterMetaType("eth::Secret"); - qRegisterMetaType("eth::Address"); - qRegisterMetaType("QmlAccount*"); - qRegisterMetaType("QmlEthereum*"); - - qmlRegisterType("org.ethereum", 1, 0, "Ethereum"); - qmlRegisterType("org.ethereum", 1, 0, "Account"); - qmlRegisterSingletonType("org.ethereum", 1, 0, "Balance", QmlEthereum::constructU256Helper); - qmlRegisterSingletonType("org.ethereum", 1, 0, "Key", QmlEthereum::constructKeyHelper); -*/ - /* - ui->librariesView->setModel(m_libraryMan); - ui->graphsView->setModel(m_graphMan); - */ - - - - -// QQmlContext* context = m_view->rootContext(); -// context->setContextProperty("u256", new U256Helper(this)); -} - -Main::~Main() -{ -} - -// extra bits needed to link on VS -#ifdef _MSC_VER - -// include moc file, ofuscated to hide from automoc -#include\ -"moc_MainWin.cpp" - -#endif diff --git a/iethxi/MainWin.h b/iethxi/MainWin.h deleted file mode 100644 index acbea8ca8..000000000 --- a/iethxi/MainWin.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef MAIN_H -#define MAIN_H - -#include - -class Main: public QObject -{ - Q_OBJECT - -public: - explicit Main(QWidget *parent = 0); - ~Main(); - -private: - QQmlApplicationEngine* m_view; -}; - -#endif // MAIN_H diff --git a/iethxi/Resources.qrc b/iethxi/Resources.qrc deleted file mode 100644 index 1789216ed..000000000 --- a/iethxi/Resources.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - Simple.qml - - diff --git a/iethxi/Simple.qml b/iethxi/Simple.qml deleted file mode 100644 index ac9dc5e37..000000000 --- a/iethxi/Simple.qml +++ /dev/null @@ -1,9 +0,0 @@ -import QtQuick.Controls 1.1 - -ApplicationWindow { - title: "My App" - Button { - text: "Push Me" - anchors.centerIn: parent - } -} diff --git a/iethxi/main.cpp b/iethxi/main.cpp deleted file mode 100644 index 569b6d17c..000000000 --- a/iethxi/main.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - QQmlApplicationEngine app(QUrl("qrc:/Simple.qml")); - return a.exec(); -} diff --git a/libpyserpent/CMakeLists.txt b/libpyserpent/CMakeLists.txt deleted file mode 100644 index 1ffa49ac0..000000000 --- a/libpyserpent/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -cmake_policy(SET CMP0015 NEW) - -aux_source_directory(. SRC_LIST) - -set(EXECUTABLE pyserpent) - -file(GLOB HEADERS "*.h") - -# set(CMAKE_INSTALL_PREFIX ../lib) -add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) - -include_directories(..) - -target_link_libraries(${EXECUTABLE} serpent) -target_link_libraries(${EXECUTABLE} lll) -target_link_libraries(${EXECUTABLE} evmcore) -target_link_libraries(${EXECUTABLE} devcore) -target_link_libraries(${EXECUTABLE} ${PYTHON_LS}) - -install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) -install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) - diff --git a/libpyserpent/pyserpent.cpp b/libpyserpent/pyserpent.cpp deleted file mode 100644 index ff8813fcf..000000000 --- a/libpyserpent/pyserpent.cpp +++ /dev/null @@ -1,173 +0,0 @@ -#include -#include "structmember.h" - -#include -#include -#include -#include - -#define PYMETHOD(name, FROM, method, TO) \ - static PyObject * name(PyObject *, PyObject *args) { \ - try { \ - FROM(med) \ - return TO(method(med)); \ - } \ - catch (std::string e) { \ - PyErr_SetString(PyExc_Exception, e.c_str()); \ - return NULL; \ - } \ - } - -#define FROMSTR(v) \ - const char *command; \ - int len; \ - if (!PyArg_ParseTuple(args, "s#", &command, &len)) \ - return NULL; \ - std::string v = std::string(command, len); \ - -#define FROMNODE(v) \ - PyObject *node; \ - if (!PyArg_ParseTuple(args, "O", &node)) \ - return NULL; \ - Node v = cppifyNode(node); - -#define FROMLIST(v) \ - PyObject *node; \ - if (!PyArg_ParseTuple(args, "O", &node)) \ - return NULL; \ - std::vector v = cppifyNodeList(node); - -// Convert metadata into python wrapper form [file, ln, ch] -PyObject* pyifyMetadata(Metadata m) { - PyObject* a = PyList_New(0); - PyList_Append(a, Py_BuildValue("s#", m.file.c_str(), m.file.length())); - PyList_Append(a, Py_BuildValue("i", m.ln)); - PyList_Append(a, Py_BuildValue("i", m.ch)); - return a; -} - -// Convert node into python wrapper form -// [token=0/astnode=1, val, metadata, args] -PyObject* pyifyNode(Node n) { - PyObject* a = PyList_New(0); - PyList_Append(a, Py_BuildValue("i", n.type == ASTNODE)); - PyList_Append(a, Py_BuildValue("s#", n.val.c_str(), n.val.length())); - PyList_Append(a, pyifyMetadata(n.metadata)); - for (unsigned i = 0; i < n.args.size(); i++) - PyList_Append(a, pyifyNode(n.args[i])); - return a; -} - -// Convert string into python wrapper form -PyObject* pyifyString(std::string s) { - return Py_BuildValue("s#", s.c_str(), s.length()); -} - -// Convert list of nodes into python wrapper form -PyObject* pyifyNodeList(std::vector n) { - PyObject* a = PyList_New(0); - for (unsigned i = 0; i < n.size(); i++) - PyList_Append(a, pyifyNode(n[i])); - return a; -} - -// Convert pyobject int into normal form -int cppifyInt(PyObject* o) { - int out; - if (!PyArg_Parse(o, "i", &out)) - err("Argument should be integer", Metadata()); - return out; -} - -// Convert pyobject string into normal form -std::string cppifyString(PyObject* o) { - const char *command; - if (!PyArg_Parse(o, "s", &command)) - err("Argument should be string", Metadata()); - return std::string(command); -} - -// Convert metadata from python wrapper form -Metadata cppifyMetadata(PyObject* o) { - std::string file = cppifyString(PyList_GetItem(o, 0)); - int ln = cppifyInt(PyList_GetItem(o, 1)); - int ch = cppifyInt(PyList_GetItem(o, 2)); - return Metadata(file, ln, ch); -} - -// Convert node from python wrapper form -Node cppifyNode(PyObject* o) { - Node n; - int isAstNode = cppifyInt(PyList_GetItem(o, 0)); - n.type = isAstNode ? ASTNODE : TOKEN; - n.val = cppifyString(PyList_GetItem(o, 1)); - n.metadata = cppifyMetadata(PyList_GetItem(o, 2)); - std::vector args; - for (int i = 3; i < PyList_Size(o); i++) { - args.push_back(cppifyNode(PyList_GetItem(o, i))); - } - n.args = args; - return n; -} - -//Convert list of nodes into normal form -std::vector cppifyNodeList(PyObject* o) { - std::vector out; - for (int i = 0; i < PyList_Size(o); i++) { - out.push_back(cppifyNode(PyList_GetItem(o,i))); - } - return out; -} - -PYMETHOD(ps_compile, FROMSTR, compile, pyifyString) -PYMETHOD(ps_compile_chunk, FROMSTR, compileChunk, pyifyString) -PYMETHOD(ps_compile_to_lll, FROMSTR, compileToLLL, pyifyNode) -PYMETHOD(ps_compile_chunk_to_lll, FROMSTR, compileChunkToLLL, pyifyNode) -PYMETHOD(ps_compile_lll, FROMNODE, compileLLL, pyifyString) -PYMETHOD(ps_parse, FROMSTR, parseSerpent, pyifyNode) -PYMETHOD(ps_rewrite, FROMNODE, rewrite, pyifyNode) -PYMETHOD(ps_rewrite_chunk, FROMNODE, rewriteChunk, pyifyNode) -PYMETHOD(ps_pretty_compile, FROMSTR, prettyCompile, pyifyNodeList) -PYMETHOD(ps_pretty_compile_chunk, FROMSTR, prettyCompileChunk, pyifyNodeList) -PYMETHOD(ps_pretty_compile_lll, FROMNODE, prettyCompileLLL, pyifyNodeList) -PYMETHOD(ps_serialize, FROMLIST, serialize, pyifyString) -PYMETHOD(ps_deserialize, FROMSTR, deserialize, pyifyNodeList) -PYMETHOD(ps_parse_lll, FROMSTR, parseLLL, pyifyNode) - - -static PyMethodDef PyextMethods[] = { - {"compile", ps_compile, METH_VARARGS, - "Compile code."}, - {"compile_chunk", ps_compile_chunk, METH_VARARGS, - "Compile code chunk (no wrappers)."}, - {"compile_to_lll", ps_compile_to_lll, METH_VARARGS, - "Compile code to LLL."}, - {"compile_chunk_to_lll", ps_compile_chunk_to_lll, METH_VARARGS, - "Compile code chunk to LLL (no wrappers)."}, - {"compile_lll", ps_compile_lll, METH_VARARGS, - "Compile LLL to EVM."}, - {"parse", ps_parse, METH_VARARGS, - "Parse serpent"}, - {"rewrite", ps_rewrite, METH_VARARGS, - "Rewrite parsed serpent to LLL"}, - {"rewrite_chunk", ps_rewrite_chunk, METH_VARARGS, - "Rewrite parsed serpent to LLL (no wrappers)"}, - {"pretty_compile", ps_pretty_compile, METH_VARARGS, - "Compile to EVM opcodes"}, - {"pretty_compile_chunk", ps_pretty_compile_chunk, METH_VARARGS, - "Compile chunk to EVM opcodes (no wrappers)"}, - {"pretty_compile_lll", ps_pretty_compile_lll, METH_VARARGS, - "Compile LLL to EVM opcodes"}, - {"serialize", ps_serialize, METH_VARARGS, - "Convert EVM opcodes to bin"}, - {"deserialize", ps_deserialize, METH_VARARGS, - "Convert EVM bin to opcodes"}, - {"parse_lll", ps_parse_lll, METH_VARARGS, - "Parse LLL"}, - {NULL, NULL, 0, NULL} /* Sentinel */ -}; - -PyMODINIT_FUNC initserpent_pyext(void) -{ - Py_InitModule( "serpent_pyext", PyextMethods ); -} diff --git a/libqethereum/QmlEthereum.cpp b/libqethereum/QmlEthereum.cpp deleted file mode 100644 index 812247b36..000000000 --- a/libqethereum/QmlEthereum.cpp +++ /dev/null @@ -1,180 +0,0 @@ -#if ETH_QTQML -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include "QmlEthereum.h" -using namespace std; - -// types -using dev::bytes; -using dev::bytesConstRef; -using dev::h160; -using dev::h256; -using dev::u160; -using dev::u256; -using dev::u256s; -using dev::RLP; -using dev::Address; -using dev::eth::BlockInfo; -using dev::eth::Client; -using dev::eth::Instruction; -using dev::KeyPair; -using dev::eth::NodeMode; -using dev::Secret; -using dev::eth::Transaction; -using dev::p2p::PeerInfo; - -// functions -using dev::toHex; -using dev::fromHex; -using dev::right160; -using dev::simpleDebugOut; -using dev::toLog2; -using dev::toString; -using dev::eth::disassemble; -using dev::eth::formatBalance; -using dev::eth::units; - -// vars -using dev::g_logPost; -using dev::g_logVerbosity; - -// Horrible global for the mainwindow. Needed for the QmlEthereums to find the Main window which acts as multiplexer for now. -// Can get rid of this once we've sorted out ITC for signalling & multiplexed querying. -dev::eth::Client* g_qmlClient; -QObject* g_qmlMain; -#if 0 -QmlAccount::QmlAccount(QObject*) -{ -} - -QmlAccount::~QmlAccount() -{ -} - -void QmlAccount::setEthereum(QmlEthereum* _eth) -{ - if (m_eth == _eth) - return; -// if (m_eth) -// disconnect(m_eth, SIGNAL(changed()), this, SIGNAL(changed())); - m_eth = _eth; -// if (m_eth) -// connect(m_eth, SIGNAL(changed()), this, SIGNAL(changed())); - ethChanged(); -// changed(); -} - -dev::u256 QmlAccount::balance() const -{ - if (m_eth) - return m_eth->balanceAt(m_address); - return u256(0); -} - -double QmlAccount::txCount() const -{ - if (m_eth) - return m_eth->txCountAt(m_address); - return 0; -} - -bool QmlAccount::isContract() const -{ - if (m_eth) - return m_eth->isContractAt(m_address); - return 0; -} - -QmlEthereum::QmlEthereum(QObject* _p): QObject(_p) -{ -// connect(g_qmlMain, SIGNAL(changed()), SIGNAL(changed())); -} - -QmlEthereum::~QmlEthereum() -{ -} - -Client* QmlEthereum::client() const -{ - return g_qmlClient; -} - -Address QmlEthereum::coinbase() const -{ - return client()->address(); -} - -void QmlEthereum::setCoinbase(Address _a) -{ - if (client()->address() != _a) - { - client()->setAddress(_a); -// changed(); - } -} - -u256 QmlEthereum::balanceAt(Address _a) const -{ - return client()->postState().balance(_a); -} - -bool QmlEthereum::isContractAt(Address _a) const -{ - return client()->postState().addressHasCode(_a); -} - -bool QmlEthereum::isMining() const -{ - return client()->isMining(); -} - -bool QmlEthereum::isListening() const -{ - return client()->haveNetwork(); -} - -void QmlEthereum::setMining(bool _l) -{ - if (_l) - client()->startMining(); - else - client()->stopMining(); -} - -void QmlEthereum::setListening(bool _l) -{ - if (_l) - client()->startNetwork(); - else - client()->stopNetwork(); -} - -double QmlEthereum::txCountAt(Address _a) const -{ - return (double)client()->postState().transactionsFrom(_a); -} - -unsigned QmlEthereum::peerCount() const -{ - return (unsigned)client()->peerCount(); -} - -void QmlEthereum::transact(Secret _secret, u256 _amount, u256 _gasPrice, u256 _gas, QByteArray _init) -{ - client()->transact(_secret, _amount, bytes(_init.data(), _init.data() + _init.size()), _gas, _gasPrice); -} - -void QmlEthereum::transact(Secret _secret, Address _dest, u256 _amount, u256 _gasPrice, u256 _gas, QByteArray _data) -{ - client()->transact(_secret, _amount, _dest, bytes(_data.data(), _data.data() + _data.size()), _gas, _gasPrice); -} - -#endif - diff --git a/libqethereum/QmlEthereum.h b/libqethereum/QmlEthereum.h deleted file mode 100644 index d242540a1..000000000 --- a/libqethereum/QmlEthereum.h +++ /dev/null @@ -1,283 +0,0 @@ -#pragma once - -#include -#if ETH_QTQML -#include -#endif -#include -#include - -namespace dev { namespace eth { -class Client; -class State; -}} - -class QQmlEngine; -class QmlAccount; -class QmlEthereum; - -extern dev::eth::Client* g_qmlClient; -extern QObject* g_qmlMain; - -Q_DECLARE_METATYPE(dev::u256) -Q_DECLARE_METATYPE(dev::Address) -Q_DECLARE_METATYPE(dev::Secret) -Q_DECLARE_METATYPE(dev::KeyPair) -//Q_DECLARE_METATYPE(QmlAccount*) -//Q_DECLARE_METATYPE(QmlEthereum*) - -class QmlU256Helper: public QObject -{ - Q_OBJECT - -public: - QmlU256Helper(QObject* _p = nullptr): QObject(_p) {} - - Q_INVOKABLE dev::u256 add(dev::u256 _a, dev::u256 _b) const { return _a + _b; } - Q_INVOKABLE dev::u256 sub(dev::u256 _a, dev::u256 _b) const { return _a - _b; } - Q_INVOKABLE dev::u256 mul(dev::u256 _a, int _b) const { return _a * _b; } - Q_INVOKABLE dev::u256 mul(int _a, dev::u256 _b) const { return _a * _b; } - Q_INVOKABLE dev::u256 div(dev::u256 _a, int _b) const { return _a / _b; } - - Q_INVOKABLE dev::u256 wei(double _s) const { return (dev::u256)_s; } - Q_INVOKABLE dev::u256 szabo(double _s) const { return (dev::u256)(_s * (double)dev::eth::szabo); } - Q_INVOKABLE dev::u256 finney(double _s) const { return (dev::u256)(_s * (double)dev::eth::finney); } - Q_INVOKABLE dev::u256 ether(double _s) const { return (dev::u256)(_s * (double)dev::eth::ether); } - Q_INVOKABLE dev::u256 wei(unsigned _s) const { return (dev::u256)_s; } - Q_INVOKABLE dev::u256 szabo(unsigned _s) const { return (dev::u256)(_s * dev::eth::szabo); } - Q_INVOKABLE dev::u256 finney(unsigned _s) const { return (dev::u256)(_s * dev::eth::finney); } - Q_INVOKABLE dev::u256 ether(unsigned _s) const { return (dev::u256)(_s * dev::eth::ether); } - Q_INVOKABLE double toWei(dev::u256 _t) const { return (double)_t; } - Q_INVOKABLE double toSzabo(dev::u256 _t) const { return toWei(_t) / (double)dev::eth::szabo; } - Q_INVOKABLE double toFinney(dev::u256 _t) const { return toWei(_t) / (double)dev::eth::finney; } - Q_INVOKABLE double toEther(dev::u256 _t) const { return toWei(_t) / (double)dev::eth::ether; } - - Q_INVOKABLE double value(dev::u256 _t) const { return (double)_t; } - - Q_INVOKABLE QString stringOf(dev::u256 _t) const { return QString::fromStdString(dev::eth::formatBalance(_t)); } -}; - -class QmlKeyHelper: public QObject -{ - Q_OBJECT - -public: - QmlKeyHelper(QObject* _p = nullptr): QObject(_p) {} - - Q_INVOKABLE dev::KeyPair create() const { return dev::KeyPair::create(); } - Q_INVOKABLE dev::Address address(dev::KeyPair _p) const { return _p.address(); } - Q_INVOKABLE dev::Secret secret(dev::KeyPair _p) const { return _p.secret(); } - Q_INVOKABLE dev::KeyPair keypair(dev::Secret _k) const { return dev::KeyPair(_k); } - - Q_INVOKABLE bool isNull(dev::Address _a) const { return !_a; } - - Q_INVOKABLE dev::Address addressOf(QString _s) const { return dev::Address(_s.toStdString()); } - Q_INVOKABLE QString stringOf(dev::Address _a) const { return QString::fromStdString(dev::toHex(_a.asArray())); } - Q_INVOKABLE QString toAbridged(dev::Address _a) const { return QString::fromStdString(_a.abridged()); } -}; -#if 0 -class QmlAccount: public QObject -{ - Q_OBJECT - -public: - QmlAccount(QObject* _p = nullptr); - virtual ~QmlAccount(); - - Q_INVOKABLE QmlEthereum* ethereum() const { return m_eth; } - Q_INVOKABLE dev::u256 balance() const; - Q_INVOKABLE double txCount() const; - Q_INVOKABLE bool isContract() const; - Q_INVOKABLE dev::Address address() const { return m_address; } - - // TODO: past transactions models. - -public slots: - void setEthereum(QmlEthereum* _eth); - void setAddress(dev::Address _a) { m_address = _a; } - -signals: - void changed(); - void ethChanged(); - -private: - QmlEthereum* m_eth = nullptr; - dev::Address m_address; - - Q_PROPERTY(dev::u256 balance READ balance NOTIFY changed STORED false) - Q_PROPERTY(double txCount READ txCount NOTIFY changed STORED false) - Q_PROPERTY(bool isContract READ isContract NOTIFY changed STORED false) - Q_PROPERTY(dev::Address address READ address WRITE setAddress NOTIFY changed) - Q_PROPERTY(QmlEthereum* ethereum READ ethereum WRITE setEthereum NOTIFY ethChanged) -}; - -class QmlEthereum: public QObject -{ - Q_OBJECT - -public: - QmlEthereum(QObject* _p = nullptr); - virtual ~QmlEthereum(); - - dev::eth::Client* client() const; - - static QObject* constructU256Helper(QQmlEngine*, QJSEngine*) { return new QmlU256Helper; } - static QObject* constructKeyHelper(QQmlEngine*, QJSEngine*) { return new QmlKeyHelper; } - - Q_INVOKABLE dev::Address coinbase() const; - - Q_INVOKABLE bool isListening() const; - Q_INVOKABLE bool isMining() const; - - Q_INVOKABLE dev::u256 balanceAt(dev::Address _a) const; - Q_INVOKABLE double txCountAt(dev::Address _a) const; - Q_INVOKABLE bool isContractAt(dev::Address _a) const; - - Q_INVOKABLE unsigned peerCount() const; - - Q_INVOKABLE QmlEthereum* self() { return this; } - -public slots: - void transact(dev::Secret _secret, dev::Address _dest, dev::u256 _amount, dev::u256 _gasPrice, dev::u256 _gas, QByteArray _data); - void transact(dev::Secret _secret, dev::u256 _amount, dev::u256 _gasPrice, dev::u256 _gas, QByteArray _init); - void setCoinbase(dev::Address); - void setMining(bool _l); - - void setListening(bool _l); - -signals: - void coinbaseChanged(); -// void netChanged(); -// void miningChanged(); - -private: - Q_PROPERTY(dev::Address coinbase READ coinbase WRITE setCoinbase NOTIFY coinbaseChanged) - Q_PROPERTY(bool listening READ isListening WRITE setListening) - Q_PROPERTY(bool mining READ isMining WRITE setMining) -}; -#endif -#if 0 -template T to(QVariant const& _s) { if (_s.type() != QVariant::String) return T(); auto s = _s.toString().toLatin1(); assert(s.size() == sizeof(T)); return *(T*)s.data(); } -template QVariant toQJS(T const& _s) { QLatin1String ret((char*)&_s, sizeof(T)); assert(QVariant(QString(ret)).toString().toLatin1().size() == sizeof(T)); assert(*(T*)(QVariant(QString(ret)).toString().toLatin1().data()) == _s); return QVariant(QString(ret)); } - -class U256Helper: public QObject -{ - Q_OBJECT - -public: - U256Helper(QObject* _p = nullptr): QObject(_p) {} - - static dev::u256 in(QVariant const& _s) { return to(_s); } - static QVariant out(dev::u256 const& _s) { return toQJS(_s); } - - Q_INVOKABLE QVariant add(QVariant _a, QVariant _b) const { return out(in(_a) + in(_b)); } - Q_INVOKABLE QVariant sub(QVariant _a, QVariant _b) const { return out(in(_a) - in(_b)); } - Q_INVOKABLE QVariant mul(QVariant _a, int _b) const { return out(in(_a) * in(_b)); } - Q_INVOKABLE QVariant mul(int _a, QVariant _b) const { return out(in(_a) * in(_b)); } - Q_INVOKABLE QVariant div(QVariant _a, int _b) const { return out(in(_a) / in(_b)); } - - Q_INVOKABLE QVariant wei(double _s) const { return out(dev::u256(_s)); } - Q_INVOKABLE QVariant szabo(double _s) const { return out(dev::u256(_s * (double)dev::eth::szabo)); } - Q_INVOKABLE QVariant finney(double _s) const { return out(dev::u256(_s * (double)dev::eth::finney)); } - Q_INVOKABLE QVariant ether(double _s) const { return out(dev::u256(_s * (double)dev::eth::ether)); } - Q_INVOKABLE QVariant wei(unsigned _s) const { return value(_s); } - Q_INVOKABLE QVariant szabo(unsigned _s) const { return out(dev::u256(_s) * dev::eth::szabo); } - Q_INVOKABLE QVariant finney(unsigned _s) const { return out(dev::u256(_s) * dev::eth::finney); } - Q_INVOKABLE QVariant ether(unsigned _s) const { return out(dev::u256(_s) * dev::eth::ether); } - Q_INVOKABLE double toWei(QVariant _t) const { return toValue(_t); } - Q_INVOKABLE double toSzabo(QVariant _t) const { return toWei(_t) / (double)dev::eth::szabo; } - Q_INVOKABLE double toFinney(QVariant _t) const { return toWei(_t) / (double)dev::eth::finney; } - Q_INVOKABLE double toEther(QVariant _t) const { return toWei(_t) / (double)dev::eth::ether; } - - Q_INVOKABLE QVariant value(unsigned _s) const { return out(dev::u256(_s)); } - Q_INVOKABLE double toValue(QVariant _t) const { return (double)in(_t); } - - Q_INVOKABLE QString ethOf(QVariant _t) const { return QString::fromStdString(dev::eth::formatBalance(in(_t))); } - Q_INVOKABLE QString stringOf(QVariant _t) const { return QString::fromStdString(dev::eth::toString(in(_t))); } - - Q_INVOKABLE QByteArray bytesOf(QVariant _t) const { dev::h256 b = in(_t); return QByteArray((char const*)&b, sizeof(dev::h256)); } - Q_INVOKABLE QVariant fromHex(QString _s) const { return out((dev::u256)dev::h256(_s.toStdString())); } - - Q_INVOKABLE QVariant fromAddress(QVariant/*dev::Address*/ _a) const { return out((dev::eth::u160)to(_a)); } - Q_INVOKABLE QVariant toAddress(QVariant/*dev::Address*/ _a) const { return toQJS((dev::eth::u160)in(_a)); } - - Q_INVOKABLE bool isNull(QVariant/*dev::Address*/ _a) const { return !in(_a); } -}; - -class KeyHelper: public QObject -{ - Q_OBJECT - -public: - KeyHelper(QObject* _p = nullptr): QObject(_p) {} - - static dev::Address in(QVariant const& _s) { return to(_s); } - static QVariant out(dev::Address const& _s) { return toQJS(_s); } - - Q_INVOKABLE QVariant/*dev::KeyPair*/ create() const { return toQJS(dev::KeyPair::create()); } - Q_INVOKABLE QVariant/*dev::Address*/ address(QVariant/*dev::KeyPair*/ _p) const { return out(to(_p).address()); } - Q_INVOKABLE QVariant/*dev::Secret*/ secret(QVariant/*dev::KeyPair*/ _p) const { return toQJS(to(_p).secret()); } - Q_INVOKABLE QVariant/*dev::KeyPair*/ keypair(QVariant/*dev::Secret*/ _k) const { return toQJS(dev::KeyPair(to(_k))); } - - Q_INVOKABLE bool isNull(QVariant/*dev::Address*/ _a) const { return !in(_a); } - - Q_INVOKABLE QVariant/*dev::Address*/ addressOf(QString _s) const { return out(dev::Address(_s.toStdString())); } - Q_INVOKABLE QString stringOf(QVariant/*dev::Address*/ _a) const { return QString::fromStdString(dev::eth::toHex(in(_a).asArray())); } - Q_INVOKABLE QString toAbridged(QVariant/*dev::Address*/ _a) const { return QString::fromStdString(in(_a).abridged()); } - -}; - -class BytesHelper: public QObject -{ - Q_OBJECT - -public: - BytesHelper(QObject* _p = nullptr): QObject(_p) {} - - Q_INVOKABLE QByteArray concat(QVariant _v, QVariant _w) const - { - QByteArray ba; - if (_v.type() == QVariant::ByteArray) - ba = _v.toByteArray(); - else - ba = _v.toString().toLatin1(); - QByteArray ba2; - if (_w.type() == QVariant::ByteArray) - ba2 = _w.toByteArray(); - else - ba2 = _w.toString().toLatin1(); - ba.append(ba2); - return QByteArray(ba); - } - Q_INVOKABLE QByteArray concat(QByteArray _v, QByteArray _w) const - { - _v.append(_w); - return _v; - } - Q_INVOKABLE QByteArray fromString(QString _s) const - { - return _s.toLatin1(); - } - Q_INVOKABLE QByteArray fromString(QString _s, unsigned _padding) const - { - QByteArray b = _s.toLatin1(); - for (unsigned i = b.size(); i < _padding; ++i) - b.append((char)0); - b.resize(_padding); - return b; - } - Q_INVOKABLE QString toString(QByteArray _b) const - { - while (_b.size() && !_b[_b.size() - 1]) - _b.resize(_b.size() - 1); - return QString::fromLatin1(_b); - } - Q_INVOKABLE QVariant u256of(QByteArray _s) const - { - while (_s.size() < 32) - _s.append((char)0); - dev::h256 ret((uint8_t const*)_s.data(), dev::h256::ConstructFromPointer); - return toQJS(ret); - } -}; -#endif diff --git a/walleth/CMakeLists.txt b/walleth/CMakeLists.txt deleted file mode 100644 index 44bf5f0f9..000000000 --- a/walleth/CMakeLists.txt +++ /dev/null @@ -1,102 +0,0 @@ -cmake_policy(SET CMP0015 NEW) - -if ("${TARGET_PLATFORM}" STREQUAL "w64") - cmake_policy(SET CMP0020 NEW) -endif () - - -set(CMAKE_INCLUDE_CURRENT_DIR ON) -aux_source_directory(. SRC_LIST) - -include_directories(..) -link_directories(../libethcore) -link_directories(../libethereum) -link_directories(../libqethereum) - -# Find Qt5 for Apple and update src_list for windows -if (APPLE) - # homebrew defaults to qt4 and installs qt5 as 'keg-only' - # which places it into /usr/local/opt insteadof /usr/local. - - set(CMAKE_PREFIX_PATH /usr/local/opt/qt5) - include_directories(/usr/local/opt/qt5/include /usr/local/include) -elseif ("${TARGET_PLATFORM}" STREQUAL "w64") - set(SRC_LIST ${SRC_LIST} ../windows/qt_plugin_import.cpp) -elseif (UNIX) - set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ";$ENV{QTDIR}/lib/cmake") -endif () - - -find_package(Qt5Widgets REQUIRED) -find_package(Qt5Gui REQUIRED) -find_package(Qt5Quick REQUIRED) -find_package(Qt5Qml REQUIRED) -find_package(Qt5Network REQUIRED) -qt5_wrap_ui(ui_Main.h Main.ui) -qt5_add_resources(RESOURCE_ADDED Resources.qrc) - -# Set name of binary and add_executable() -if (APPLE) - set(EXECUTEABLE Walleth) - set(CMAKE_INSTALL_PREFIX ./) - set(BIN_INSTALL_DIR ".") - set(DOC_INSTALL_DIR ".") - - set(PROJECT_VERSION "${ETH_VERSION}") - set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_NAME} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}") - set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}") - set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}") - set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTEABLE}) - include(BundleUtilities) - - add_executable(${EXECUTEABLE} MACOSX_BUNDLE Main.ui ${RESOURCE_ADDED} ${SRC_LIST}) -else () - set(EXECUTEABLE walleth) - add_executable(${EXECUTEABLE} Main.ui ${RESOURCE_ADDED} ${SRC_LIST}) -endif () - -qt5_use_modules(${EXECUTEABLE} Core Gui Widgets Network Quick Qml) -target_link_libraries(${EXECUTEABLE} qethereum ethereum secp256k1) - -if (APPLE) - if (${ADDFRAMEWORKS}) - set_target_properties(${EXECUTEABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") - endif () - - SET_SOURCE_FILES_PROPERTIES(${EXECUTEABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) - - # This is a workaround for when the build-type defaults to Debug, and when a multi-config generator like xcode is used, where the type - # will not be set but defaults to release. - set(generator_lowercase "${CMAKE_GENERATOR}") - string(TOLOWER "${CMAKE_GENERATOR}" generator_lowercase) - if ("${generator_lowercase}" STREQUAL "xcode") - # TODO: Not sure how to resolve this. Possibly \${TARGET_BUILD_DIR} - set(binary_build_dir "${CMAKE_CURRENT_BINARY_DIR}/Debug") - else () - set(binary_build_dir "${CMAKE_CURRENT_BINARY_DIR}") - endif () - - set(APPS ${binary_build_dir}/${EXECUTEABLE}.app) - - # This tool and the next will automatically looked at the linked libraries in order to determine what dependencies are required. Thus, target_link_libaries only needs to add ethereum and secp256k1 (above) - install(CODE " - include(BundleUtilities) - set(BU_CHMOD_BUNDLE_ITEMS 1) - fixup_bundle(\"${APPS}\" \"${BUNDLELIBS}\" \"../libqethereum ../libethereum ../secp256k1\") - " COMPONENT RUNTIME ) - - if (${ADDFRAMEWORKS}) - add_custom_target(addframeworks ALL - COMMAND /usr/local/opt/qt5/bin/macdeployqt ${binary_build_dir}/${EXECUTEABLE}.app - WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - DEPENDS ${PROJECT_NAME} - ) - endif () - -else () - install( TARGETS ${EXECUTEABLE} RUNTIME DESTINATION bin ) -endif () - diff --git a/walleth/EthereumMacOSXBundleInfo.plist.in b/walleth/EthereumMacOSXBundleInfo.plist.in deleted file mode 100644 index 684ad7908..000000000 --- a/walleth/EthereumMacOSXBundleInfo.plist.in +++ /dev/null @@ -1,38 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${MACOSX_BUNDLE_EXECUTABLE_NAME} - CFBundleGetInfoString - ${MACOSX_BUNDLE_INFO_STRING} - CFBundleIconFile - ${MACOSX_BUNDLE_ICON_FILE} - CFBundleIdentifier - ${MACOSX_BUNDLE_GUI_IDENTIFIER} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - ${MACOSX_BUNDLE_LONG_VERSION_STRING} - CFBundleName - ${MACOSX_BUNDLE_BUNDLE_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - ${MACOSX_BUNDLE_SHORT_VERSION_STRING} - CFBundleSignature - ???? - CFBundleVersion - ${MACOSX_BUNDLE_BUNDLE_VERSION} - CSResourcesFileMapped - - LSRequiresCarbon - - NSHumanReadableCopyright - ${MACOSX_BUNDLE_COPYRIGHT} - NSHighResolutionCapable - - - diff --git a/walleth/Main.ui b/walleth/Main.ui deleted file mode 100644 index 6904590a8..000000000 --- a/walleth/Main.ui +++ /dev/null @@ -1,168 +0,0 @@ - - - Main - - - - 0 - 0 - 562 - 488 - - - - Walleth - - - true - - - QMainWindow::AllowNestedDocks|QMainWindow::AllowTabbedDocks|QMainWindow::VerticalTabs - - - true - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - 0 wei - - - - - - - 0 peers - - - - - - - 1 block - - - - - - - - - - - 0 - 0 - 562 - 20 - - - - - &File - - - - - - &Network - - - - - - - - T&ools - - - - - - - - &Help - - - - - - - - - - - - &Quit - - - - - true - - - true - - - Use &UPnP - - - - - &Connect to Peer... - - - - - true - - - Enable &Network - - - - - true - - - &Mine - - - - - &New Address - - - - - &About... - - - - - true - - - &Preview - - - - - - - diff --git a/walleth/MainWin.cpp b/walleth/MainWin.cpp deleted file mode 100644 index f56cad65d..000000000 --- a/walleth/MainWin.cpp +++ /dev/null @@ -1,286 +0,0 @@ -#include -#include -//#include -//#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "BuildInfo.h" -#include "MainWin.h" -#include "ui_Main.h" -using namespace std; - -// types -using dev::bytes; -using dev::bytesConstRef; -using dev::h160; -using dev::h256; -using dev::u160; -using dev::u256; -using dev::u256s; -using dev::Address; -using dev::eth::BlockInfo; -using dev::eth::Client; -using dev::eth::Instruction; -using dev::KeyPair; -using dev::eth::NodeMode; -using dev::p2p::PeerInfo; -using dev::RLP; -using dev::Secret; -using dev::eth::Transaction; - -// functions -using dev::toHex; -using dev::fromHex; -using dev::right160; -using dev::simpleDebugOut; -using dev::toLog2; -using dev::toString; -using dev::eth::units; -using dev::eth::disassemble; -using dev::eth::formatBalance; - -// vars -using dev::g_logPost; -using dev::g_logVerbosity; - -Main::Main(QWidget *parent) : - QMainWindow(parent), - ui(new Ui::Main) -{ - setWindowFlags(Qt::Window); - ui->setupUi(this); - setWindowIcon(QIcon(":/Ethereum.png")); - - g_qmlMain = this; - - m_client.reset(new Client("Walleth", Address(), dev::getDataDir() + "/Walleth")); - - g_qmlClient = m_client.get(); - - qRegisterMetaType("dev::u256"); - qRegisterMetaType("dev::KeyPair"); - qRegisterMetaType("dev::Secret"); - qRegisterMetaType("dev::Address"); - qRegisterMetaType("QmlAccount*"); - qRegisterMetaType("QmlEthereum*"); - - qmlRegisterType("org.ethereum", 1, 0, "Ethereum"); - qmlRegisterType("org.ethereum", 1, 0, "Account"); - qmlRegisterSingletonType("org.ethereum", 1, 0, "Balance", QmlEthereum::constructU256Helper); - qmlRegisterSingletonType("org.ethereum", 1, 0, "Key", QmlEthereum::constructKeyHelper); - - /* - ui->librariesView->setModel(m_libraryMan); - ui->graphsView->setModel(m_graphMan); - */ - - m_view = new QQuickView(); - -// QQmlContext* context = m_view->rootContext(); -// context->setContextProperty("u256", new U256Helper(this)); - - m_view->setSource(QUrl("qrc:/Simple.qml")); - - QWidget* w = QWidget::createWindowContainer(m_view); - m_view->setResizeMode(QQuickView::SizeRootObjectToView); - ui->fullDisplay->insertWidget(0, w); - m_view->create(); - -// m_timelinesItem = m_view->rootObject()->findChild("timelines"); - - readSettings(); - refresh(); - - m_refreshNetwork = new QTimer(this); - connect(m_refreshNetwork, SIGNAL(timeout()), SLOT(refreshNetwork())); - m_refreshNetwork->start(1000); - - connect(&m_webCtrl, &QNetworkAccessManager::finished, [&](QNetworkReply* _r) - { - m_servers = QString::fromUtf8(_r->readAll()).split("\n", QString::SkipEmptyParts); - if (m_servers.size()) - { - ui->net->setChecked(true); - on_net_triggered(true); - } - }); - QNetworkRequest r(QUrl("http://www.ethereum.org/servers.poc" + QString(dev::Version).section('.', 1, 1) + ".txt")); - r.setHeader(QNetworkRequest::UserAgentHeader, "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1712.0 Safari/537.36"); - m_webCtrl.get(r); - srand(time(0)); - - startTimer(200); - - statusBar()->addPermanentWidget(ui->balance); - statusBar()->addPermanentWidget(ui->peerCount); - statusBar()->addPermanentWidget(ui->blockCount); -} - -Main::~Main() -{ - writeSettings(); -} - -void Main::timerEvent(QTimerEvent *) -{ - -} - -void Main::on_about_triggered() -{ - QMessageBox::about(this, "About Walleth PoC-" + QString(dev::Version).section('.', 1, 1), QString("Walleth/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM) "\n" DEV_QUOTED(ETH_COMMIT_HASH) + (ETH_CLEAN_REPO ? "\nCLEAN" : "\n+ LOCAL CHANGES") + "\n\nBy Gav Wood, 2014.\nBased on a design by Vitalik Buterin.\n\nThanks to the various contributors including: Alex Leverington, Tim Hughes, caktux, Eric Lombrozo, Marko Simovic."); -} - -void Main::writeSettings() -{ - QSettings s("ethereum", "walleth"); - QByteArray b; - b.resize(sizeof(Secret) * m_myKeys.size()); - auto p = b.data(); - for (auto i: m_myKeys) - { - memcpy(p, &(i.secret()), sizeof(Secret)); - p += sizeof(Secret); - } - s.setValue("address", b); - - s.setValue("upnp", ui->upnp->isChecked()); - s.setValue("clientName", m_clientName); - s.setValue("idealPeers", m_idealPeers); - s.setValue("port", m_port); - - bytes d = client()->savePeers(); - if (d.size()) - m_peers = QByteArray((char*)d.data(), (int)d.size()); - s.setValue("peers", m_peers); - - s.setValue("geometry", saveGeometry()); - s.setValue("windowState", saveState()); -} - -void Main::readSettings() -{ - QSettings s("ethereum", "walleth"); - - restoreGeometry(s.value("geometry").toByteArray()); - restoreState(s.value("windowState").toByteArray()); - - QByteArray b = s.value("address").toByteArray(); - if (b.isEmpty()) - m_myKeys.append(KeyPair::create()); - else - { - h256 k; - for (unsigned i = 0; i < b.size() / sizeof(Secret); ++i) - { - memcpy(&k, b.data() + i * sizeof(Secret), sizeof(Secret)); - m_myKeys.append(KeyPair(k)); - } - } - //m_eth->setAddress(m_myKeys.last().address()); - m_peers = s.value("peers").toByteArray(); - ui->upnp->setChecked(s.value("upnp", true).toBool()); - m_clientName = s.value("clientName", "").toString(); - m_idealPeers = s.value("idealPeers", 5).toInt(); - m_port = s.value("port", 30303).toInt(); -} - -void Main::refreshNetwork() -{ - auto ps = client()->peers(); - ui->peerCount->setText(QString::fromStdString(toString(ps.size())) + " peer(s)"); -} - -void Main::refresh() -{ - auto d = client()->blockChain().details(); - auto diff = BlockInfo(client()->blockChain().block()).difficulty; - ui->blockCount->setText(QString("#%1 @%3 T%2").arg(d.number).arg(toLog2(d.totalDifficulty)).arg(toLog2(diff))); - - m_keysChanged = false; - u256 totalBalance = 0; - for (auto i: m_myKeys) - { - u256 b = m_client->balanceAt(i.address()); - totalBalance += b; - } - ui->balance->setText(QString::fromStdString(formatBalance(totalBalance))); -} - -void Main::on_net_triggered(bool _auto) -{ - string n = string("Walleth/v") + dev::Version; - if (m_clientName.size()) - n += "/" + m_clientName.toStdString(); - n += "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM); - client()->setClientVersion(n); - if (ui->net->isChecked()) - { - if (_auto) - { - QString s = m_servers[rand() % m_servers.size()]; - client()->startNetwork(m_port, s.section(':', 0, 0).toStdString(), s.section(':', 1).toInt(), NodeMode::Full, m_idealPeers, "", ui->upnp->isChecked()); - } - else - client()->startNetwork(m_port, string(), 0, NodeMode::Full, m_idealPeers, "", ui->upnp->isChecked()); - if (m_peers.size()) - client()->restorePeers(bytesConstRef((byte*)m_peers.data(), m_peers.size())); - } - else - client()->stopNetwork(); -} - -void Main::on_connect_triggered() -{ - if (!ui->net->isChecked()) - { - ui->net->setChecked(true); - on_net_triggered(); - } - bool ok = false; - QString s = QInputDialog::getItem(this, "Connect to a Network Peer", "Enter a peer to which a connection may be made:", m_servers, m_servers.count() ? rand() % m_servers.count() : 0, true, &ok); - if (ok && s.contains(":")) - { - string host = s.section(":", 0, 0).toStdString(); - unsigned short port = s.section(":", 1).toInt(); - client()->connect(host, port); - } -} - -void Main::on_mine_triggered() -{ - if (ui->mine->isChecked()) - { - client()->setAddress(m_myKeys.last().address()); - client()->startMining(); - } - else - client()->stopMining(); -} - -void Main::on_create_triggered() -{ - m_myKeys.append(KeyPair::create()); - m_keysChanged = true; -} - -// extra bits needed to link on VS -#ifdef _MSC_VER - -// include moc file, ofuscated to hide from automoc -#include\ -"moc_MainWin.cpp" - -// include qrc content -#include\ -"qrc_Resources.cpp" - -#endif diff --git a/walleth/MainWin.h b/walleth/MainWin.h deleted file mode 100644 index 860db8bc9..000000000 --- a/walleth/MainWin.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef MAIN_H -#define MAIN_H - -#include -#include -#include -#include -#include -#include - -namespace Ui { -class Main; -} - -namespace dev { namespace eth { -class Client; -class State; -}} - -class QQuickView; -class QQmlEngine; -class QJSEngine; - -class Main : public QMainWindow -{ - Q_OBJECT - -public: - explicit Main(QWidget *parent = 0); - ~Main(); - - dev::eth::Client* client() const { return m_client.get(); } - -private slots: - void on_connect_triggered(); - void on_mine_triggered(); - void on_create_triggered(); - void on_net_triggered(bool _auto = false); - void on_about_triggered(); - void on_preview_triggered() { refresh(); } - void on_quit_triggered() { close(); } - - void refresh(); - void refreshNetwork(); - -protected: - virtual void timerEvent(QTimerEvent *); - -private: -/* QString pretty(dev::Address _a) const; - QString render(dev::Address _a) const; - dev::Address fromString(QString const& _a) const; -*/ - dev::eth::State const& state() const; - - void updateFee(); - void readSettings(); - void writeSettings(); - - dev::u256 fee() const; - dev::u256 total() const; - dev::u256 value() const; - - std::unique_ptr ui; - - QByteArray m_peers; - QMutex m_guiLock; - QTimer* m_refresh; - QTimer* m_refreshNetwork; - QVector m_myKeys; - bool m_keysChanged = false; - int m_port; - int m_idealPeers; - QString m_clientName; - QStringList m_servers; - - QQuickView* m_view; - - QNetworkAccessManager m_webCtrl; - - std::unique_ptr m_client; -}; - -#endif // MAIN_H diff --git a/walleth/Resources.qrc b/walleth/Resources.qrc deleted file mode 100644 index 1789216ed..000000000 --- a/walleth/Resources.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - Simple.qml - - diff --git a/walleth/Simple.qml b/walleth/Simple.qml deleted file mode 100644 index 53cb7def4..000000000 --- a/walleth/Simple.qml +++ /dev/null @@ -1,38 +0,0 @@ -import QtQml 2.2 -import QtQuick 2.1 -import QtQuick.Controls 1.0 -import QtQuick.Layouts 1.0 -import Qt.labs.settings 1.0 -import org.ethereum 1.0 - -Item { - id: main - anchors.fill: parent - anchors.margins: 9 - -// Qt.application.name: "Walleth" -// Qt.application.organization: "Ethereum" -// Qt.application.domain: "org.ethereum" - - Ethereum { - id: eth - } - - Account { - id: myAccount - address: Key.addressOf("84fc4ba9373c30bfe32d8c5a502854e7f1175878") - ethereum: eth - // TODO: state: eth.latest // could be eth.pending - // will provide balance, txCount, isContract, incomingTransactions (list model), outgoingTransactions (list model). - // transaction lists' items will provide value, from, to, final balance. - } - - // KeyPair provides makeTransaction(recvAddress, value, data (array)) - - Text { - text: "Balance: " + Balance.stringOf(myAccount.balance) + " [" + myAccount.txCount + "]" + "\nAccount: " + Key.stringOf(myAccount.address) - Layout.minimumHeight: 30 - Layout.fillHeight: true - Layout.fillWidth: true - } -} diff --git a/walleth/main.cpp b/walleth/main.cpp deleted file mode 100644 index 42afd5e66..000000000 --- a/walleth/main.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "MainWin.h" -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - Main w; - w.show(); - - return a.exec(); -} From c14cb82acd78d366cf2de0263fd473254ad3b032 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 12 Dec 2014 12:50:57 +0100 Subject: [PATCH 141/277] removed LANGUAGES command line option --- CMakeLists.txt | 59 +++++++++++++++++--------------------- libdevcrypto/TrieDB.cpp | 4 --- libethcore/BlockInfo.cpp | 4 --- libethcore/ProofOfWork.cpp | 3 -- 4 files changed, 26 insertions(+), 44 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d6bf59636..98da62bdc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,6 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") # Normally, set(...CACHE...) creates cache variables, but does not modify them. function(createDefaultCacheConfig) set(HEADLESS OFF CACHE BOOL "Do not compile GUI (AlethZero)") - set(LANGUAGES OFF CACHE BOOL "Limit build to Serpent/LLL tools") set(VMTRACE OFF CACHE BOOL "VM tracing and run-time checks (useful for cross-implementation VM debugging)") set(PARANOIA OFF CACHE BOOL "Additional run-time checks") set(JSONRPC ON CACHE BOOL "Build with jsonprc. default on") @@ -24,10 +23,6 @@ endfunction() # propagates CMake configuration options to the compiler function(configureProject) - if (LANGUAGES) - add_definitions(-DETH_LANGUAGES) - endif () - if (PARANOIA) if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") add_definitions(-DETH_PARANOIA) @@ -89,7 +84,7 @@ cmake_policy(SET CMP0015 NEW) createDefaultCacheConfig() configureProject() -message("-- LANGUAGES: ${LANGUAGES}; VMTRACE: ${VMTRACE}; PARANOIA: ${PARANOIA}; HEADLESS: ${HEADLESS}; JSONRPC: ${JSONRPC}") +message("-- VMTRACE: ${VMTRACE}; PARANOIA: ${PARANOIA}; HEADLESS: ${HEADLESS}; JSONRPC: ${JSONRPC}") # Default TARGET_PLATFORM to "linux". @@ -125,40 +120,38 @@ if (JSONRPC) add_subdirectory(libweb3jsonrpc) endif() -if (NOT LANGUAGES) - add_subdirectory(secp256k1) - add_subdirectory(libp2p) - add_subdirectory(libdevcrypto) - add_subdirectory(libwhisper) +add_subdirectory(secp256k1) +add_subdirectory(libp2p) +add_subdirectory(libdevcrypto) +add_subdirectory(libwhisper) - add_subdirectory(libethcore) - add_subdirectory(libevm) - add_subdirectory(libethereum) +add_subdirectory(libethcore) +add_subdirectory(libevm) +add_subdirectory(libethereum) # TODO is this 'TODO remove' still valid? # add_subdirectory(libethereumx) # TODO remove - add_subdirectory(libwebthree) - add_subdirectory(test) - add_subdirectory(eth) - if("x${CMAKE_BUILD_TYPE}" STREQUAL "xDebug") - add_subdirectory(exp) - endif () +add_subdirectory(libwebthree) +add_subdirectory(test) +add_subdirectory(eth) +if("x${CMAKE_BUILD_TYPE}" STREQUAL "xDebug") + add_subdirectory(exp) +endif () - # TODO check msvc - if(NOT ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")) - add_subdirectory(neth) - endif () +# TODO check msvc +if(NOT ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")) + add_subdirectory(neth) +endif () - if (NOT HEADLESS) - - add_subdirectory(libjsqrc) - add_subdirectory(libqethereum) - add_subdirectory(alethzero) - add_subdirectory(third) - add_subdirectory(mix) - - endif() +if (NOT HEADLESS) + + add_subdirectory(libjsqrc) + add_subdirectory(libqethereum) + add_subdirectory(alethzero) + add_subdirectory(third) + add_subdirectory(mix) + endif() enable_testing() diff --git a/libdevcrypto/TrieDB.cpp b/libdevcrypto/TrieDB.cpp index 674f21aa4..6f476c14b 100644 --- a/libdevcrypto/TrieDB.cpp +++ b/libdevcrypto/TrieDB.cpp @@ -24,9 +24,5 @@ using namespace std; using namespace dev; -#if !ETH_LANGUAGES - h256 const dev::c_shaNull = sha3(rlp("")); h256 const dev::EmptyTrie = c_shaNull; - -#endif diff --git a/libethcore/BlockInfo.cpp b/libethcore/BlockInfo.cpp index fbf056867..bf973b565 100644 --- a/libethcore/BlockInfo.cpp +++ b/libethcore/BlockInfo.cpp @@ -19,8 +19,6 @@ * @date 2014 */ -#if !ETH_LANGUAGES - #include #include #include @@ -197,5 +195,3 @@ void BlockInfo::verifyParent(BlockInfo const& _parent) const BOOST_THROW_EXCEPTION(InvalidNumber()); } } - -#endif diff --git a/libethcore/ProofOfWork.cpp b/libethcore/ProofOfWork.cpp index bfb8942cc..181e379b5 100644 --- a/libethcore/ProofOfWork.cpp +++ b/libethcore/ProofOfWork.cpp @@ -19,8 +19,6 @@ * @date 2014 */ -#if !ETH_LANGUAGES - #include #include #include @@ -107,4 +105,3 @@ h256 DaggerEvaluator::eval(h256 const& _root, h256 const& _nonce) } } -#endif From 15c78c848cccdd7db787216b3f001cb0ced903c1 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 12 Dec 2014 13:13:29 +0100 Subject: [PATCH 142/277] jsonrpc _library -> _libraries --- cmake/FindJsonRpcCpp.cmake | 15 +++++++-------- libqethereum/CMakeLists.txt | 3 +-- libweb3jsonrpc/CMakeLists.txt | 3 +-- test/CMakeLists.txt | 8 ++++---- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/cmake/FindJsonRpcCpp.cmake b/cmake/FindJsonRpcCpp.cmake index 221180337..eecf518f8 100644 --- a/cmake/FindJsonRpcCpp.cmake +++ b/cmake/FindJsonRpcCpp.cmake @@ -7,6 +7,8 @@ # This module defines # JSON_RCP_CPP_INCLUDE_DIRS, where to find header, etc. # JSON_RCP_CPP_LIBRARIES, the libraries needed to use json-rpc-cpp. +# JSON_RPC_CPP_SERVER_LIBRARIES, the libraries needed to use json-rpc-cpp-server +# JSON_RPC_CPP_CLIENT_LIBRARIES, the libraries needed to use json-rpc-cpp-client # JSON_RCP_CPP_FOUND, If false, do not try to use json-rpc-cpp. # only look in default directories @@ -35,8 +37,11 @@ find_library( DOC "json-rpc-cpp client library" ) -# message (" - json-rcp-cpp header : ${JSON_RPC_CPP_INCLUDE_DIRS}") -# message (" - json-rcp-cpp lib : ${JSON_RPC_CPP_LIBRARIES}") +# these are the variables to be uses by the calling script +set (JSON_RPC_CPP_INCLUDE_DIRS ${JSON_RPC_CPP_INCLUDE_DIR}) +set (JSON_RPC_CPP_LIBRARIES ${JSON_RPC_CPP_COMMON_LIBRARY} ${JSON_RPC_CPP_SERVER_LIBRARY} ${JSON_RPC_CPP_CLIENT_LIBRARY}) +set (JSON_RPC_CPP_SERVER_LIBRARIES ${JSON_RPC_CPP_COMMON_LIBRARY} ${JSON_RPC_CPP_SERVER_LIBRARY}) +set (JSON_RPC_CPP_CLIENT_LIBRARIES ${JSON_RPC_CPP_COMMON_LIBRARY} ${JSON_RPC_CPP_CLIENT_LIBRARY}) # handle the QUIETLY and REQUIRED arguments and set JSON_RPC_CPP_FOUND to TRUE # if all listed variables are TRUE, hide their existence from configuration view @@ -45,9 +50,3 @@ find_package_handle_standard_args(json_rpc_cpp DEFAULT_MSG JSON_RPC_CPP_COMMON_LIBRARY JSON_RPC_CPP_SERVER_LIBRARY JSON_RPC_CPP_CLIENT_LIBRARY JSON_RPC_CPP_INCLUDE_DIR) mark_as_advanced (JSON_RPC_CPP_COMMON_LIBRARY JSON_RPC_CPP_SERVER_LIBRARY JSON_RPC_CPP_CLIENT_LIBRARY JSON_RPC_CPP_INCLUDE_DIR) -# these are the variables to be uses by the calling script -set (JSON_RPC_CPP_INCLUDE_DIRS ${JSON_RPC_CPP_INCLUDE_DIR}) -set (JSON_RPC_CPP_LIBRARIES ${JSON_RPC_CPP_COMMON_LIBRARY} ${JSON_RPC_CPP_SERVER_LIBRARY} ${JSON_RPC_CPP_CLIENT_LIBRARY}) - -# message (" - json-rcp-cpp header : ${JSON_RPC_CPP_INCLUDE_DIRS}") -# message (" - json-rcp-cpp lib : ${JSON_RPC_CPP_LIBRARIES}") diff --git a/libqethereum/CMakeLists.txt b/libqethereum/CMakeLists.txt index e2c8f9a05..683bfec56 100644 --- a/libqethereum/CMakeLists.txt +++ b/libqethereum/CMakeLists.txt @@ -33,8 +33,7 @@ target_link_libraries(${EXECUTABLE} Qt5::Widgets) target_link_libraries(${EXECUTABLE} Qt5::Network) target_link_libraries(${EXECUTABLE} Qt5::Quick) target_link_libraries(${EXECUTABLE} Qt5::Qml) -target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_COMMON_LIBRARY}) -target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_SERVER_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_SERVER_LIBRARIES}) target_link_libraries(${EXECUTABLE} ethereum) target_link_libraries(${EXECUTABLE} secp256k1) diff --git a/libweb3jsonrpc/CMakeLists.txt b/libweb3jsonrpc/CMakeLists.txt index 9a0771ef7..5068ede56 100644 --- a/libweb3jsonrpc/CMakeLists.txt +++ b/libweb3jsonrpc/CMakeLists.txt @@ -25,8 +25,7 @@ endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES}) -target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_COMMON_LIBRARY}) -target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_SERVER_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_SERVER_LIBRARIES}) if (MINIUPNPC_FOUND) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARIES}) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 73003e805..7e618f7ea 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -12,19 +12,19 @@ file(GLOB HEADERS "*.h") add_executable(testeth ${SRC_LIST} ${HEADERS}) add_executable(createRandomTest createRandomTest.cpp vm.cpp TestHelper.cpp) +target_link_libraries(testeth ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE}) +target_link_libraries(testeth ${CURL_LIBRARIES}) target_link_libraries(testeth ethereum) target_link_libraries(testeth ethcore) target_link_libraries(testeth secp256k1) target_link_libraries(testeth solidity) target_link_libraries(testeth webthree) -target_link_libraries(testeth ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE}) -target_link_libraries(testeth ${CURL_LIBRARIES}) if (JSONRPC) target_link_libraries(testeth web3jsonrpc) - target_link_libraries(testeth ${JSON_RPC_CPP_CLIENT_LIBRARY}) + target_link_libraries(testeth ${JSON_RPC_CPP_CLIENT_LIBRARIES}) endif() +target_link_libraries(createRandomTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE}) target_link_libraries(createRandomTest ethereum) target_link_libraries(createRandomTest ethcore) -target_link_libraries(createRandomTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE}) From 4da294f86d984efb60293a979b703722f2785e9a Mon Sep 17 00:00:00 2001 From: yann300 Date: Fri, 12 Dec 2014 14:01:26 +0100 Subject: [PATCH 143/277] - CommonJS => fromString(string _sn) fromString(string const& _sn). - Wrapping string with QApplication::tr(), used for localization. --- libdevcore/CommonJS.cpp | 7 +------ libdevcore/CommonJS.h | 2 +- mix/AssemblyDebuggerCtrl.cpp | 5 ++--- mix/AssemblyDebuggerModel.cpp | 3 ++- mix/ConstantCompilationCtrl.cpp | 6 +++--- mix/ConstantCompilationModel.cpp | 3 ++- mix/KeyEventManager.cpp | 2 -- 7 files changed, 11 insertions(+), 17 deletions(-) diff --git a/libdevcore/CommonJS.cpp b/libdevcore/CommonJS.cpp index 9dc04b7e7..ad3ade71f 100644 --- a/libdevcore/CommonJS.cpp +++ b/libdevcore/CommonJS.cpp @@ -105,13 +105,8 @@ std::string fromRaw(h256 _n, unsigned* _inc) return ""; } -Address fromString(std::string _sn) +Address fromString(std::string const& _sn) { - if (_sn.size() > 32) - _sn.resize(32); - h256 n; - memcpy(n.data(), _sn.data(), _sn.size()); - memset(n.data() + _sn.size(), 0, 32 - _sn.size()); if (_sn.size() == 40) return Address(fromHex(_sn)); else diff --git a/libdevcore/CommonJS.h b/libdevcore/CommonJS.h index 0fb087f72..8b96b2e68 100644 --- a/libdevcore/CommonJS.h +++ b/libdevcore/CommonJS.h @@ -51,7 +51,7 @@ bytes padded(bytes _b, unsigned _l); bytes unpadded(bytes _s); std::string prettyU256(u256 _n); std::string fromRaw(h256 _n, unsigned* _inc = nullptr); -Address fromString(std::string _a); +Address fromString(std::string const& _a); template FixedHash jsToFixed(std::string const& _s) { diff --git a/mix/AssemblyDebuggerCtrl.cpp b/mix/AssemblyDebuggerCtrl.cpp index 36318ccb7..678f94d77 100644 --- a/mix/AssemblyDebuggerCtrl.cpp +++ b/mix/AssemblyDebuggerCtrl.cpp @@ -47,7 +47,7 @@ QString AssemblyDebuggerCtrl::contentUrl() const QString AssemblyDebuggerCtrl::title() const { - return "debugger"; + return QApplication::tr("debugger"); } void AssemblyDebuggerCtrl::start() const @@ -63,7 +63,6 @@ void AssemblyDebuggerCtrl::keyPressed(int _key) QString code = m_doc->toPlainText(); QtConcurrent::run([this, code]() { - if (!m_modelDebugger->compile(m_doc->toPlainText())) { emit dataAvailable(false, DebuggingStatusResult::Compilationfailed); @@ -101,5 +100,5 @@ void AssemblyDebuggerCtrl::updateGUI(bool success, DebuggingStatusResult reason, this->addContentOn(this); } else - m_ctx->displayMessageDialog("debugger","compilation failed"); + m_ctx->displayMessageDialog(QApplication::tr("debugger"), QApplication::tr("compilation failed")); } diff --git a/mix/AssemblyDebuggerModel.cpp b/mix/AssemblyDebuggerModel.cpp index bcf58835c..ad6ba156d 100644 --- a/mix/AssemblyDebuggerModel.cpp +++ b/mix/AssemblyDebuggerModel.cpp @@ -17,6 +17,7 @@ * used as a model to debug contract assembly code. */ +#include #include "libethereum/Executive.h" #include "libethereum/Transaction.h" #include "libethereum/ExtVM.h" @@ -90,7 +91,7 @@ DebuggingContent AssemblyDebuggerModel::getContractInitiationDebugStates(dev::u2 { DebuggingContent r; r.contentAvailable = false; - r.message = "compile failed"; + r.message = QApplication::tr("compilation failed"); return r; } diff --git a/mix/ConstantCompilationCtrl.cpp b/mix/ConstantCompilationCtrl.cpp index 8b0577d93..3ccd87f77 100644 --- a/mix/ConstantCompilationCtrl.cpp +++ b/mix/ConstantCompilationCtrl.cpp @@ -43,7 +43,7 @@ QString ConstantCompilationCtrl::contentUrl() const QString ConstantCompilationCtrl::title() const { - return "compiler"; + return QApplication::tr("compiler"); } void ConstantCompilationCtrl::start() const @@ -80,13 +80,13 @@ void ConstantCompilationCtrl::writeOutPut(CompilerResult const& _res) status->setProperty("text", "succeeded"); status->setProperty("color", "green"); content->setProperty("text", _res.hexCode); - qDebug() << QString("compile succeeded " + _res.hexCode); + qDebug() << QString(QApplication::tr("compile succeeded") + " " + _res.hexCode); } else { status->setProperty("text", "failure"); status->setProperty("color", "red"); content->setProperty("text", _res.comment); - qDebug() << QString("compile failed " + _res.comment); + qDebug() << QString(QApplication::tr("compile failed") + " " + _res.comment); } } diff --git a/mix/ConstantCompilationModel.cpp b/mix/ConstantCompilationModel.cpp index f50ac805b..817d01635 100644 --- a/mix/ConstantCompilationModel.cpp +++ b/mix/ConstantCompilationModel.cpp @@ -20,6 +20,7 @@ * Ethereum IDE client. */ +#include #include #include #include @@ -55,7 +56,7 @@ CompilerResult ConstantCompilationModel::compile(QString _code) catch (...) { res.success = false; - res.comment = "Uncaught exception."; + res.comment = QApplication::tr("Uncaught exception."); res.hexCode = ""; } return res; diff --git a/mix/KeyEventManager.cpp b/mix/KeyEventManager.cpp index f5d638869..c32caadb8 100644 --- a/mix/KeyEventManager.cpp +++ b/mix/KeyEventManager.cpp @@ -39,5 +39,3 @@ void KeyEventManager::keyPressed(QVariant _event) { emit onKeyPressed(_event.toInt()); } - - From e113ce92dd5fe94330586d0abb8ba16435aa0923 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 12 Dec 2014 14:04:53 +0100 Subject: [PATCH 144/277] removed unused libs/includes from libethcore --- libethcore/All.h | 7 ------- libethcore/CMakeLists.txt | 5 +---- 2 files changed, 1 insertion(+), 11 deletions(-) delete mode 100644 libethcore/All.h diff --git a/libethcore/All.h b/libethcore/All.h deleted file mode 100644 index cb1d3f5a3..000000000 --- a/libethcore/All.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "BlockInfo.h" -#include "CommonEth.h" -#include "ProofOfWork.h" -#include "Exceptions.h" - diff --git a/libethcore/CMakeLists.txt b/libethcore/CMakeLists.txt index 960936b3a..984aa3ce5 100644 --- a/libethcore/CMakeLists.txt +++ b/libethcore/CMakeLists.txt @@ -9,8 +9,7 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) -include_directories(${CRYPTOPP_INCLUDE_DIRS}) -include_directories(${LEVELDB_INCLUDE_DIRS}) +include_directories(${Boost_INCLUDE_DIRS}) include_directories(..) set(EXECUTABLE ethcore) @@ -23,10 +22,8 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} devcore) -target_link_libraries(${EXECUTABLE} secp256k1) install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) From 0f00ede521613776811c956573a3252dfccf13ca Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 12 Dec 2014 14:25:55 +0100 Subject: [PATCH 145/277] removed unused libs/includes from libdevcrypto --- libdevcrypto/All.h | 8 -------- libdevcrypto/CMakeLists.txt | 2 +- libethcore/CommonEth.cpp | 1 - 3 files changed, 1 insertion(+), 10 deletions(-) delete mode 100644 libdevcrypto/All.h diff --git a/libdevcrypto/All.h b/libdevcrypto/All.h deleted file mode 100644 index 9070725e9..000000000 --- a/libdevcrypto/All.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include "Common.h" -#include "AES.h" -#include "ECDHE.h" -#include "FileSystem.h" -#include "SHA3.h" -#include "TrieDB.h" diff --git a/libdevcrypto/CMakeLists.txt b/libdevcrypto/CMakeLists.txt index 354053483..c0fa56026 100644 --- a/libdevcrypto/CMakeLists.txt +++ b/libdevcrypto/CMakeLists.txt @@ -9,6 +9,7 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) +include_directories(${Boost_INCLUDE_DIRS}) include_directories(${CRYPTOPP_INCLUDE_DIRS}) include_directories(${LEVELDB_INCLUDE_DIRS}) include_directories(..) @@ -26,7 +27,6 @@ target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY_RELEASE}) target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) target_link_libraries(${EXECUTABLE} devcore) -target_link_libraries(${EXECUTABLE} secp256k1) install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/libethcore/CommonEth.cpp b/libethcore/CommonEth.cpp index 36726dae4..5e510572e 100644 --- a/libethcore/CommonEth.cpp +++ b/libethcore/CommonEth.cpp @@ -21,7 +21,6 @@ #include "CommonEth.h" #include -#include #include #include "Exceptions.h" using namespace std; From 70f3e2be09161e49081b80a4581f7ea2b8021f09 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 12 Dec 2014 14:34:11 +0100 Subject: [PATCH 146/277] removed unused libs/includes from libevm --- libdevcore/All.h | 8 -------- libevm/CMakeLists.txt | 8 -------- 2 files changed, 16 deletions(-) delete mode 100644 libdevcore/All.h diff --git a/libdevcore/All.h b/libdevcore/All.h deleted file mode 100644 index eac152d42..000000000 --- a/libdevcore/All.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include "Common.h" -#include "CommonData.h" -#include "CommonIO.h" -#include "FixedHash.h" -#include "Log.h" -#include "RLP.h" diff --git a/libevm/CMakeLists.txt b/libevm/CMakeLists.txt index 94f7e5e79..5b7f39323 100644 --- a/libevm/CMakeLists.txt +++ b/libevm/CMakeLists.txt @@ -12,7 +12,6 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) include_directories(..) -include_directories(${LEVELDB_INCLUDE_DIRS}) set(EXECUTABLE evm) @@ -24,17 +23,10 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) - -if (MINIUPNPC_FOUND) - target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARIES}) -endif() - target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} evmcore) target_link_libraries(${EXECUTABLE} devcore) -target_link_libraries(${EXECUTABLE} secp256k1) install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) From 1da073190a2253d4dc0e34d42ec0d799566385e9 Mon Sep 17 00:00:00 2001 From: ethdev Date: Fri, 12 Dec 2014 14:37:42 +0100 Subject: [PATCH 147/277] fixed windows --- libevm/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/libevm/CMakeLists.txt b/libevm/CMakeLists.txt index 5b7f39323..a260b442c 100644 --- a/libevm/CMakeLists.txt +++ b/libevm/CMakeLists.txt @@ -11,6 +11,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) +include_directories(${Boost_INCLUDE_DIRS}) include_directories(..) set(EXECUTABLE evm) From 1fcf85ae0ac4bb825dcd37f10c3f15473417c8d4 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 12 Dec 2014 14:45:49 +0100 Subject: [PATCH 148/277] removed unnecessary miniupnpc links --- eth/CMakeLists.txt | 4 ---- exp/CMakeLists.txt | 4 ---- libethereum/CMakeLists.txt | 4 ---- libevm/CMakeLists.txt | 2 ++ libp2p/CMakeLists.txt | 8 ++++---- libweb3jsonrpc/CMakeLists.txt | 4 ---- libwebthree/CMakeLists.txt | 4 ---- libwhisper/CMakeLists.txt | 4 ---- neth/CMakeLists.txt | 4 ---- 9 files changed, 6 insertions(+), 32 deletions(-) diff --git a/eth/CMakeLists.txt b/eth/CMakeLists.txt index 9996d1170..739c2991c 100644 --- a/eth/CMakeLists.txt +++ b/eth/CMakeLists.txt @@ -17,10 +17,6 @@ add_dependencies(${EXECUTABLE} BuildInfo.h) target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARY_RELEASE}) target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY_RELEASE}) -if (MINIUPNPC_FOUND) - target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARIES}) -endif() - if (READLINE_FOUND) target_link_libraries(${EXECUTABLE} ${READLINE_LIBRARIES}) endif() diff --git a/exp/CMakeLists.txt b/exp/CMakeLists.txt index 98eae7baf..49bbbf16b 100644 --- a/exp/CMakeLists.txt +++ b/exp/CMakeLists.txt @@ -12,10 +12,6 @@ add_executable(${EXECUTABLE} ${SRC_LIST}) target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) -if (MINIUPNPC_FOUND) - target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARIES}) -endif() - target_link_libraries(${EXECUTABLE} ethereum) target_link_libraries(${EXECUTABLE} p2p) target_link_libraries(${EXECUTABLE} gmp) diff --git a/libethereum/CMakeLists.txt b/libethereum/CMakeLists.txt index c13f2ba18..792ed0cf1 100644 --- a/libethereum/CMakeLists.txt +++ b/libethereum/CMakeLists.txt @@ -27,10 +27,6 @@ endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARY_RELEASE}) -if (MINIUPNPC_FOUND) - target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARIES}) -endif() - target_link_libraries(${EXECUTABLE} evm) target_link_libraries(${EXECUTABLE} lll) target_link_libraries(${EXECUTABLE} whisper) diff --git a/libevm/CMakeLists.txt b/libevm/CMakeLists.txt index a260b442c..96b8f9ade 100644 --- a/libevm/CMakeLists.txt +++ b/libevm/CMakeLists.txt @@ -11,6 +11,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) +# we may not use it in libevm, but one of our dependecies is including boost in header file +# and windows is failing to build without that include_directories(${Boost_INCLUDE_DIRS}) include_directories(..) diff --git a/libp2p/CMakeLists.txt b/libp2p/CMakeLists.txt index c94ebebbd..50ca138f4 100644 --- a/libp2p/CMakeLists.txt +++ b/libp2p/CMakeLists.txt @@ -11,7 +11,10 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) +# we may not use it in libp2p, but one of our dependecies is including leveldb in header file +# and windows is failing to build without that include_directories(${LEVELDB_INCLUDE_DIRS}) +include_directories(${MINIUPNPC_INCLUDE_DIRS}) include_directories(..) set(EXECUTABLE p2p) @@ -24,15 +27,12 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) - -if(MINIUPNPC_FOUND) +if (MINIUPNPC_FOUND) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARIES}) endif() target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} devcore) -target_link_libraries(${EXECUTABLE} secp256k1) install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/libweb3jsonrpc/CMakeLists.txt b/libweb3jsonrpc/CMakeLists.txt index 5068ede56..f371024e6 100644 --- a/libweb3jsonrpc/CMakeLists.txt +++ b/libweb3jsonrpc/CMakeLists.txt @@ -27,10 +27,6 @@ target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_SERVER_LIBRARIES}) -if (MINIUPNPC_FOUND) - target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARIES}) -endif() - target_link_libraries(${EXECUTABLE} webthree) target_link_libraries(${EXECUTABLE} secp256k1) target_link_libraries(${EXECUTABLE} solidity) diff --git a/libwebthree/CMakeLists.txt b/libwebthree/CMakeLists.txt index 587d81493..1d8f23918 100644 --- a/libwebthree/CMakeLists.txt +++ b/libwebthree/CMakeLists.txt @@ -26,10 +26,6 @@ endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) -if (MINIUPNPC_FOUND) - target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARIES}) -endif() - target_link_libraries(${EXECUTABLE} ethereum) target_link_libraries(${EXECUTABLE} evm) target_link_libraries(${EXECUTABLE} lll) diff --git a/libwhisper/CMakeLists.txt b/libwhisper/CMakeLists.txt index f51af33b7..79879922e 100644 --- a/libwhisper/CMakeLists.txt +++ b/libwhisper/CMakeLists.txt @@ -26,10 +26,6 @@ endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) -if (MINIUPNPC_FOUND) - target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARIES}) -endif() - target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} devcore) diff --git a/neth/CMakeLists.txt b/neth/CMakeLists.txt index 63619fd84..4db3d2cf4 100644 --- a/neth/CMakeLists.txt +++ b/neth/CMakeLists.txt @@ -14,10 +14,6 @@ add_dependencies(${EXECUTABLE} BuildInfo.h) target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) -if (MINIUPNPC_FOUND) -target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LIBRARIES}) -endif() - if (JSONRPC) target_link_libraries(${EXECUTABLE} web3jsonrpc) endif() From 97262fa114d9559b00646dc07c97601518598a04 Mon Sep 17 00:00:00 2001 From: ethdev Date: Fri, 12 Dec 2014 14:52:24 +0100 Subject: [PATCH 149/277] windows fix for previous commit --- libp2p/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libp2p/CMakeLists.txt b/libp2p/CMakeLists.txt index 50ca138f4..6f3f6b712 100644 --- a/libp2p/CMakeLists.txt +++ b/libp2p/CMakeLists.txt @@ -14,7 +14,10 @@ aux_source_directory(. SRC_LIST) # we may not use it in libp2p, but one of our dependecies is including leveldb in header file # and windows is failing to build without that include_directories(${LEVELDB_INCLUDE_DIRS}) -include_directories(${MINIUPNPC_INCLUDE_DIRS}) + +if (MINIUPNPC_FOUND) + include_directories(${MINIUPNPC_INCLUDE_DIRS}) +endif() include_directories(..) set(EXECUTABLE p2p) From 9e2eb149af7038c3efb1bba1f80cfeb8571b1646 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 12 Dec 2014 13:33:42 +0100 Subject: [PATCH 150/277] Beginnings of cleaning up the Executive/State code. --- alethzero/MainWin.cpp | 4 +-- eth/main.cpp | 2 +- libdevcore/vector_ref.h | 1 + libethereum/Executive.cpp | 41 +++++++++++++------------ libethereum/Executive.h | 13 +++++--- libethereum/ExtVM.h | 10 +++--- libethereum/State.cpp | 51 ++++++++++++++++++++----------- libethereum/State.h | 4 +-- libevm/ExtVMFace.h | 11 +++++-- libevm/VM.h | 4 +-- test/jsonrpc.cpp | 2 +- test/solidityExecutionFramework.h | 4 +-- test/trie.cpp | 3 +- test/vm.cpp | 8 ++--- test/vm.h | 4 +-- test/whisperTopic.cpp | 5 +-- 16 files changed, 99 insertions(+), 68 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index a240f64e1..0e36c7737 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -1350,7 +1350,7 @@ void Main::on_debugCurrent_triggered() { unsigned txi = item->data(Qt::UserRole + 1).toInt(); m_executiveState = ethereum()->state(txi + 1, h); - m_currentExecution = unique_ptr(new Executive(m_executiveState)); + m_currentExecution = unique_ptr(new Executive(m_executiveState, 0)); Transaction t = m_executiveState.pending()[txi]; m_executiveState = m_executiveState.fromPending(txi); auto r = t.rlp(); @@ -1855,7 +1855,7 @@ void Main::on_debug_clicked() { Secret s = i.secret(); m_executiveState = ethereum()->postState(); - m_currentExecution = unique_ptr(new Executive(m_executiveState)); + m_currentExecution = unique_ptr(new Executive(m_executiveState, 0)); Transaction t = isCreation() ? Transaction(value(), gasPrice(), ui->gas->value(), m_data, m_executiveState.transactionsFrom(dev::toAddress(s)), s) : Transaction(value(), gasPrice(), ui->gas->value(), fromString(ui->destination->currentText()), m_data, m_executiveState.transactionsFrom(dev::toAddress(s)), s); diff --git a/eth/main.cpp b/eth/main.cpp index 0113fa1a5..49c5fdf56 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -620,7 +620,7 @@ int main(int argc, char** argv) dev::eth::State state =c->state(index + 1,c->blockChain().numberHash(block)); if (index < state.pending().size()) { - Executive e(state); + Executive e(state, 0); Transaction t = state.pending()[index]; state = state.fromPending(index); bytes r = t.rlp(); diff --git a/libdevcore/vector_ref.h b/libdevcore/vector_ref.h index be2fea13c..db46d62f6 100644 --- a/libdevcore/vector_ref.h +++ b/libdevcore/vector_ref.h @@ -40,6 +40,7 @@ public: vector_ref<_T> cropped(size_t _begin, size_t _count = ~size_t(0)) const { if (m_data && _begin + std::max(size_t(0), _count) <= m_count) return vector_ref<_T>(m_data + _begin, _count == ~size_t(0) ? m_count - _begin : _count); else return vector_ref<_T>(); } void retarget(_T const* _d, size_t _s) { m_data = _d; m_count = _s; } void retarget(std::vector<_T> const& _t) { m_data = _t.data(); m_count = _t.size(); } + void copyTo(vector_ref::type> _t) const { memcpy(_t.data(), m_data, std::min(_t.size(), m_count) * sizeof(_T)); } _T* begin() { return m_data; } _T* end() { return m_data + m_count; } diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index 007896d75..c81dd7ed8 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -19,12 +19,13 @@ * @date 2014 */ +#include "Executive.h" + #include #include #include #include #include "Interface.h" -#include "Executive.h" #include "State.h" #include "ExtVM.h" using namespace std; @@ -88,11 +89,12 @@ bool Executive::setup(bytesConstRef _rlp) if (m_t.isCreation()) return create(m_sender, m_t.value(), m_t.gasPrice(), m_t.gas() - (u256)gasCost, &m_t.data(), m_sender); else - return call(m_t.receiveAddress(), m_sender, m_t.value(), m_t.gasPrice(), bytesConstRef(&m_t.data()), m_t.gas() - (u256)gasCost, m_sender); + return call(m_t.receiveAddress(), m_t.receiveAddress(), m_sender, m_t.value(), m_t.gasPrice(), bytesConstRef(&m_t.data()), m_t.gas() - (u256)gasCost, m_sender); } -bool Executive::call(Address _receiveAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256 _gas, Address _originAddress) +bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256 _gas, Address _originAddress) { + m_isCreation = false; // cnote << "Transferring" << formatBalance(_value) << "to receiver."; m_s.addBalance(_receiveAddress, _value); @@ -109,11 +111,11 @@ bool Executive::call(Address _receiveAddress, Address _senderAddress, u256 _valu it->second.exec(_data, bytesRef()); return true; } - else if (m_s.addressHasCode(_receiveAddress)) + else if (m_s.addressHasCode(_codeAddress)) { m_vm = VMFactory::create(_gas); bytes const& c = m_s.code(_receiveAddress); - m_ext.reset(new ExtVM(m_s, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &c)); + m_ext = make_shared(m_s, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &c, m_depth); } else m_endGas = _gas; @@ -122,6 +124,8 @@ bool Executive::call(Address _receiveAddress, Address _senderAddress, u256 _valu bool Executive::create(Address _sender, u256 _endowment, u256 _gasPrice, u256 _gas, bytesConstRef _init, Address _origin) { + m_isCreation = true; + // We can allow for the reverted state (i.e. that with which m_ext is constructed) to contain the m_newAddress, since // we delete it explicitly if we decide we need to revert. m_newAddress = right160(sha3(rlpList(_sender, m_s.transactionsFrom(_sender) - 1))); @@ -131,7 +135,7 @@ bool Executive::create(Address _sender, u256 _endowment, u256 _gasPrice, u256 _g // Execute _init. m_vm = VMFactory::create(_gas); - m_ext.reset(new ExtVM(m_s, m_newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _init)); + m_ext = make_shared(m_s, m_newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _init, m_depth); return _init.empty(); } @@ -163,14 +167,18 @@ bool Executive::go(OnOpFunc const& _onOp) auto sgas = m_vm->gas(); try { - m_out = m_vm->go(*m_ext, _onOp); + m_out = m_vm->go(*m_ext, _onOp, 0); m_endGas = m_vm->gas(); m_endGas += min((m_t.gas() - m_endGas) / 2, m_ext->sub.refunds); m_logs = m_ext->sub.logs; - if (m_out.size() * c_createDataGas <= m_endGas) - m_endGas -= m_out.size() * c_createDataGas; - else - m_out.reset(); + + if (m_isCreation) + { + if (m_out.size() * c_createDataGas <= m_endGas) + m_endGas -= m_out.size() * c_createDataGas; + else + m_out.reset(); + } } catch (StepsDone const&) { @@ -184,12 +192,7 @@ bool Executive::go(OnOpFunc const& _onOp) // Write state out only in the case of a non-excepted transaction. m_ext->revert(); - // Explicitly delete a newly created address - this will still be in the reverted state. -/* if (m_newAddress) - { - m_s.m_cache.erase(m_newAddress); - m_newAddress = Address(); - }*/ + m_excepted = true; } catch (Exception const& _e) { @@ -214,12 +217,10 @@ u256 Executive::gas() const void Executive::finalize(OnOpFunc const&) { if (m_t.isCreation() && !m_ext->sub.suicides.count(m_newAddress)) - { // creation - put code in place. m_s.m_cache[m_newAddress].setCode(m_out); - } -// cnote << "Refunding" << formatBalance(m_endGas * m_ext->gasPrice) << "to origin (=" << m_endGas << "*" << formatBalance(m_ext->gasPrice) << ")"; + // cnote << "Refunding" << formatBalance(m_endGas * m_ext->gasPrice) << "to origin (=" << m_endGas << "*" << formatBalance(m_ext->gasPrice) << ")"; m_s.addBalance(m_sender, m_endGas * m_t.gasPrice()); u256 feesEarned = (m_t.gas() - m_endGas) * m_t.gasPrice(); diff --git a/libethereum/Executive.h b/libethereum/Executive.h index 9e47bbfbf..fa438f025 100644 --- a/libethereum/Executive.h +++ b/libethereum/Executive.h @@ -27,7 +27,6 @@ #include #include #include "Transaction.h" -#include "ExtVM.h" namespace dev { @@ -35,21 +34,23 @@ namespace eth { class State; +class ExtVM; struct Manifest; struct VMTraceChannel: public LogChannel { static const char* name() { return "EVM"; } static const int verbosity = 11; }; + class Executive { public: - Executive(State& _s): m_s(_s) {} + Executive(State& _s, unsigned _level): m_s(_s), m_depth(_level) {} ~Executive() = default; Executive(Executive const&) = delete; void operator=(Executive) = delete; bool setup(bytesConstRef _transaction); bool create(Address _txSender, u256 _endowment, u256 _gasPrice, u256 _gas, bytesConstRef _code, Address _originAddress); - bool call(Address _myAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256 _gas, Address _originAddress); + bool call(Address _myAddress, Address _codeAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256 _gas, Address _originAddress); bool go(OnOpFunc const& _onOp = OnOpFunc()); void finalize(OnOpFunc const& _onOp = OnOpFunc()); u256 gasUsed() const; @@ -63,6 +64,7 @@ public: bytesConstRef out() const { return m_out; } h160 newAddress() const { return m_newAddress; } LogEntries const& logs() const { return m_logs; } + bool excepted() const { return m_excepted; } VMFace const& vm() const { return *m_vm; } State const& state() const { return m_s; } @@ -70,12 +72,15 @@ public: private: State& m_s; - std::unique_ptr m_ext; + std::shared_ptr m_ext; std::unique_ptr m_vm; bytesConstRef m_out; Address m_newAddress; Transaction m_t; + bool m_isCreation; + bool m_excepted = false; + unsigned m_depth = 0; Address m_sender; u256 m_endGas; diff --git a/libethereum/ExtVM.h b/libethereum/ExtVM.h index ad1045d3f..d4937bcd5 100644 --- a/libethereum/ExtVM.h +++ b/libethereum/ExtVM.h @@ -55,17 +55,17 @@ public: virtual bytes const& codeAt(Address _a) override final { return m_s.code(_a); } /// Create a new contract. - virtual h160 create(u256 _endowment, u256* _gas, bytesConstRef _code, OnOpFunc const& _onOp = OnOpFunc()) override final + virtual h160 create(u256 _endowment, u256& io_gas, bytesConstRef _code, OnOpFunc const& _onOp = OnOpFunc()) override final { // Increment associated nonce for sender. m_s.noteSending(myAddress); - return m_s.create(myAddress, _endowment, gasPrice, _gas, _code, origin, &sub, _onOp, depth + 1); + return m_s.create(myAddress, _endowment, gasPrice, io_gas, _code, origin, sub, _onOp, depth + 1); } /// Create a new message call. Leave _myAddressOverride as the default to use the present address as caller. - virtual bool call(Address _receiveAddress, u256 _txValue, bytesConstRef _txData, u256* _gas, bytesRef _out, OnOpFunc const& _onOp = {}, Address _myAddressOverride = {}, Address _codeAddressOverride = {}) override final + virtual bool call(Address _receiveAddress, u256 _txValue, bytesConstRef _txData, u256& io_gas, bytesRef _out, OnOpFunc const& _onOp = {}, Address _myAddressOverride = {}, Address _codeAddressOverride = {}) override final { - return m_s.call(_receiveAddress, _codeAddressOverride ? _codeAddressOverride : _receiveAddress, _myAddressOverride ? _myAddressOverride : myAddress, _txValue, gasPrice, _txData, _gas, _out, origin, &sub, _onOp, depth + 1); + return m_s.call(_receiveAddress, _codeAddressOverride ? _codeAddressOverride : _receiveAddress, _myAddressOverride ? _myAddressOverride : myAddress, _txValue, gasPrice, _txData, io_gas, _out, origin, sub, _onOp, depth + 1); } /// Read address's balance. @@ -86,7 +86,7 @@ public: /// Revert any changes made (by any of the other calls). /// @TODO check call site for the parent manifest being discarded. - virtual void revert() override final { m_s.m_cache = m_origCache; } + virtual void revert() override final { m_s.m_cache = m_origCache; sub.clear(); } State& state() const { return m_s; } diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 1d6ad3480..f2b5d7283 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -1119,7 +1119,7 @@ u256 State::execute(bytesConstRef _rlp, bytes* o_output, bool _commit) auto h = rootHash(); #endif - Executive e(*this); + Executive e(*this, 0); e.setup(_rlp); u256 startGasUsed = gasUsed(); @@ -1174,8 +1174,24 @@ u256 State::execute(bytesConstRef _rlp, bytes* o_output, bool _commit) return e.gasUsed(); } -bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256* _gas, bytesRef _out, Address _originAddress, SubState* o_sub, OnOpFunc const& _onOp, unsigned _level) +bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256& io_gas, bytesRef _out, Address _originAddress, SubState& io_sub, OnOpFunc const& _onOp, unsigned _level) { +#if 0 + // TODO: TEST TEST TEST!!! + Executive e(*this, _level); + + if (!e.call(_receiveAddress, _codeAddress, _senderAddress, _value, _gasPrice, _data, io_gas, _originAddress)) + { + e.go(_onOp); + io_sub += e.ext().sub; + } + + e.out().copyTo(_out); + io_gas = e.gas(); + + return !e.excepted(); + +#else if (!_originAddress) _originAddress = _senderAddress; @@ -1186,26 +1202,25 @@ bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderA if (it != c_precompiled.end()) { bigint g = it->second.gas(_data); - if (*_gas < g) + if (io_gas < g) { - *_gas = 0; + io_gas = 0; return false; } - *_gas -= (u256)g; + io_gas -= (u256)g; it->second.exec(_data, _out); } else if (addressHasCode(_codeAddress)) { - auto vm = VMFactory::create(*_gas); + auto vm = VMFactory::create(io_gas); ExtVM evm(*this, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &code(_codeAddress), _level); try { auto out = vm->go(evm, _onOp); memcpy(_out.data(), out.data(), std::min(out.size(), _out.size())); - if (o_sub) - *o_sub += evm.sub; - *_gas = vm->gas(); + io_sub += evm.sub; + io_gas = vm->gas(); // Write state out only in the case of a non-excepted transaction. return true; } @@ -1213,7 +1228,7 @@ bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderA { clog(StateChat) << "Safe VM Exception: " << diagnostic_information(_e); evm.revert(); - *_gas = 0; + io_gas = 0; return false; } catch (Exception const& _e) @@ -1232,9 +1247,10 @@ bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderA } } return true; +#endif } -h160 State::create(Address _sender, u256 _endowment, u256 _gasPrice, u256* _gas, bytesConstRef _code, Address _origin, SubState* o_sub, OnOpFunc const& _onOp, unsigned _level) +h160 State::create(Address _sender, u256 _endowment, u256 _gasPrice, u256& io_gas, bytesConstRef _code, Address _origin, SubState& io_sub, OnOpFunc const& _onOp, unsigned _level) { if (!_origin) _origin = _sender; @@ -1245,19 +1261,18 @@ h160 State::create(Address _sender, u256 _endowment, u256 _gasPrice, u256* _gas, m_cache[newAddress] = Account(balance(newAddress) + _endowment, Account::ContractConception); // Execute init code. - auto vm = VMFactory::create(*_gas); + auto vm = VMFactory::create(io_gas); ExtVM evm(*this, newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _code, _level); bytesConstRef out; try { out = vm->go(evm, _onOp); - if (o_sub) - *o_sub += evm.sub; - *_gas = vm->gas(); + io_sub += evm.sub; + io_gas = vm->gas(); - if (out.size() * c_createDataGas <= *_gas) - *_gas -= out.size() * c_createDataGas; + if (out.size() * c_createDataGas <= io_gas) + io_gas -= out.size() * c_createDataGas; else out.reset(); @@ -1269,7 +1284,7 @@ h160 State::create(Address _sender, u256 _endowment, u256 _gasPrice, u256* _gas, { clog(StateChat) << "Safe VM Exception: " << diagnostic_information(_e); evm.revert(); - *_gas = 0; + io_gas = 0; } catch (Exception const& _e) { diff --git a/libethereum/State.h b/libethereum/State.h index 10d73f671..dd83a83ee 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -276,12 +276,12 @@ private: // We assume all instrinsic fees are paid up before this point. /// Execute a contract-creation transaction. - h160 create(Address _txSender, u256 _endowment, u256 _gasPrice, u256* _gas, bytesConstRef _code, Address _originAddress = Address(), SubState* o_sub = nullptr, OnOpFunc const& _onOp = OnOpFunc(), unsigned _level = 0); + h160 create(Address _txSender, u256 _endowment, u256 _gasPrice, u256& io_gas, bytesConstRef _code, Address _originAddress, SubState& io_sub, OnOpFunc const& _onOp, unsigned _level); /// Execute a call. /// @a _gas points to the amount of gas to use for the call, and will lower it accordingly. /// @returns false if the call ran out of gas before completion. true otherwise. - bool call(Address _myAddress, Address _codeAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256* _gas, bytesRef _out, Address _originAddress = Address(), SubState* o_sub = nullptr, OnOpFunc const& _onOp = OnOpFunc(), unsigned _level = 0); + bool call(Address _myAddress, Address _codeAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256& io_gas, bytesRef _out, Address _originAddress, SubState& io_sub, OnOpFunc const& _onOp, unsigned _level); /// Sets m_currentBlock to a clean state, (i.e. no change from m_previousBlock). void resetCurrent(); diff --git a/libevm/ExtVMFace.h b/libevm/ExtVMFace.h index 24c7dfcda..b8c4184ab 100644 --- a/libevm/ExtVMFace.h +++ b/libevm/ExtVMFace.h @@ -83,6 +83,13 @@ struct SubState logs += _s.logs; return *this; } + + void clear() + { + suicides.clear(); + logs.clear(); + refunds = 0; + } }; class ExtVMFace; @@ -129,10 +136,10 @@ public: virtual void suicide(Address) { sub.suicides.insert(myAddress); } /// Create a new (contract) account. - virtual h160 create(u256, u256*, bytesConstRef, OnOpFunc const&) { return h160(); } + virtual h160 create(u256, u256&, bytesConstRef, OnOpFunc const&) { return h160(); } /// Make a new message call. - virtual bool call(Address, u256, bytesConstRef, u256*, bytesRef, OnOpFunc const&, Address, Address) { return false; } + virtual bool call(Address, u256, bytesConstRef, u256&, bytesRef, OnOpFunc const&, Address, Address) { return false; } /// Revert any changes made (by any of the other calls). virtual void log(h256s&& _topics, bytesConstRef _data) { sub.logs.push_back(LogEntry(myAddress, std::move(_topics), _data.toBytes())); } diff --git a/libevm/VM.h b/libevm/VM.h index 6f3229920..09a1f6d26 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -798,7 +798,7 @@ inline bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _st if (_ext.depth == 1024) BOOST_THROW_EXCEPTION(OutOfGas()); _ext.subBalance(endowment); - m_stack.push_back((u160)_ext.create(endowment, &m_gas, bytesConstRef(m_temp.data() + initOff, initSize), _onOp)); + m_stack.push_back((u160)_ext.create(endowment, m_gas, bytesConstRef(m_temp.data() + initOff, initSize), _onOp)); } else m_stack.push_back(0); @@ -828,7 +828,7 @@ inline bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _st if (_ext.depth == 1024) BOOST_THROW_EXCEPTION(OutOfGas()); _ext.subBalance(value); - m_stack.push_back(_ext.call(inst == Instruction::CALL ? receiveAddress : _ext.myAddress, value, bytesConstRef(m_temp.data() + inOff, inSize), &gas, bytesRef(m_temp.data() + outOff, outSize), _onOp, Address(), receiveAddress)); + m_stack.push_back(_ext.call(inst == Instruction::CALL ? receiveAddress : _ext.myAddress, value, bytesConstRef(m_temp.data() + inOff, inSize), gas, bytesRef(m_temp.data() + outOff, outSize), _onOp, Address(), receiveAddress)); } else m_stack.push_back(0); diff --git a/test/jsonrpc.cpp b/test/jsonrpc.cpp index 20ffc6d54..970957b52 100644 --- a/test/jsonrpc.cpp +++ b/test/jsonrpc.cpp @@ -43,7 +43,7 @@ using namespace dev; using namespace dev::eth; namespace js = json_spirit; -WebThreeDirect *web3; +WebThreeDirect* web3; unique_ptr jsonrpcServer; unique_ptr jsonrpcClient; diff --git a/test/solidityExecutionFramework.h b/test/solidityExecutionFramework.h index 9d40e8a46..91ee7ad6a 100644 --- a/test/solidityExecutionFramework.h +++ b/test/solidityExecutionFramework.h @@ -117,7 +117,7 @@ private: void sendMessage(bytes const& _data, bool _isCreation, u256 const& _value = 0) { m_state.addBalance(m_sender, _value); // just in case - eth::Executive executive(m_state); + eth::Executive executive(m_state, 0); eth::Transaction t = _isCreation ? eth::Transaction(_value, m_gasPrice, m_gas, _data, 0, KeyPair::create().sec()) : eth::Transaction(_value, m_gasPrice, m_gas, m_contractAddress, _data, 0, KeyPair::create().sec()); bytes transactionRLP = t.rlp(); @@ -137,7 +137,7 @@ private: else { BOOST_REQUIRE(m_state.addressHasCode(m_contractAddress)); - BOOST_REQUIRE(!executive.call(m_contractAddress, m_sender, _value, m_gasPrice, &_data, m_gas, m_sender)); + BOOST_REQUIRE(!executive.call(m_contractAddress, m_contractAddress, m_sender, _value, m_gasPrice, &_data, m_gas, m_sender)); } BOOST_REQUIRE(executive.go()); m_state.noteSending(m_sender); diff --git a/test/trie.cpp b/test/trie.cpp index 3f072a6d1..0cf87c212 100644 --- a/test/trie.cpp +++ b/test/trie.cpp @@ -54,7 +54,6 @@ BOOST_AUTO_TEST_CASE(trie_tests) { string testPath = test::getTestPath(); - testPath += "/TrieTests"; cnote << "Testing Trie..."; @@ -245,6 +244,7 @@ BOOST_AUTO_TEST_CASE(moreTrieTests) BOOST_AUTO_TEST_CASE(trieLowerBound) { cnote << "Stress-testing Trie.lower_bound..."; + if (0) { MemoryDB dm; EnforceRefs e(dm, true); @@ -290,6 +290,7 @@ BOOST_AUTO_TEST_CASE(trieLowerBound) BOOST_AUTO_TEST_CASE(trieStess) { cnote << "Stress-testing Trie..."; + if (0) { MemoryDB m; MemoryDB dm; diff --git a/test/vm.cpp b/test/vm.cpp index d8e85383c..f05981d9e 100644 --- a/test/vm.cpp +++ b/test/vm.cpp @@ -34,18 +34,18 @@ using namespace dev::test; FakeExtVM::FakeExtVM(eth::BlockInfo const& _previousBlock, eth::BlockInfo const& _currentBlock, unsigned _depth): /// TODO: XXX: remove the default argument & fix. ExtVMFace(Address(), Address(), Address(), 0, 1, bytesConstRef(), bytes(), _previousBlock, _currentBlock, _depth) {} -h160 FakeExtVM::create(u256 _endowment, u256* _gas, bytesConstRef _init, OnOpFunc const&) +h160 FakeExtVM::create(u256 _endowment, u256& io_gas, bytesConstRef _init, OnOpFunc const&) { Address na = right160(sha3(rlpList(myAddress, get<1>(addresses[myAddress])))); - Transaction t(_endowment, gasPrice, *_gas, _init.toBytes()); + Transaction t(_endowment, gasPrice, io_gas, _init.toBytes()); callcreates.push_back(t); return na; } -bool FakeExtVM::call(Address _receiveAddress, u256 _value, bytesConstRef _data, u256* _gas, bytesRef _out, OnOpFunc const&, Address _myAddressOverride, Address _codeAddressOverride) +bool FakeExtVM::call(Address _receiveAddress, u256 _value, bytesConstRef _data, u256& io_gas, bytesRef _out, OnOpFunc const&, Address _myAddressOverride, Address _codeAddressOverride) { - Transaction t(_value, gasPrice, *_gas, _receiveAddress, _data.toVector()); + Transaction t(_value, gasPrice, io_gas, _receiveAddress, _data.toVector()); callcreates.push_back(t); (void)_out; (void)_myAddressOverride; diff --git a/test/vm.h b/test/vm.h index 3d4b88d54..ff948cbf8 100644 --- a/test/vm.h +++ b/test/vm.h @@ -55,8 +55,8 @@ public: virtual u256 txCount(Address _a) override { return std::get<1>(addresses[_a]); } virtual void suicide(Address _a) override { std::get<0>(addresses[_a]) += std::get<0>(addresses[myAddress]); addresses.erase(myAddress); } virtual bytes const& codeAt(Address _a) override { return std::get<3>(addresses[_a]); } - virtual h160 create(u256 _endowment, u256* _gas, bytesConstRef _init, eth::OnOpFunc const&) override; - virtual bool call(Address _receiveAddress, u256 _value, bytesConstRef _data, u256* _gas, bytesRef _out, eth::OnOpFunc const&, Address, Address) override; + virtual h160 create(u256 _endowment, u256& io_gas, bytesConstRef _init, eth::OnOpFunc const&) override; + virtual bool call(Address _receiveAddress, u256 _value, bytesConstRef _data, u256& io_gas, bytesRef _out, eth::OnOpFunc const&, Address, Address) override; void setTransaction(Address _caller, u256 _value, u256 _gasPrice, bytes const& _data); void setContract(Address _myAddress, u256 _myBalance, u256 _myNonce, std::map const& _storage, bytes const& _code); void set(Address _a, u256 _myBalance, u256 _myNonce, std::map const& _storage, bytes const& _code); diff --git a/test/whisperTopic.cpp b/test/whisperTopic.cpp index c5e59332d..79adf3d6a 100644 --- a/test/whisperTopic.cpp +++ b/test/whisperTopic.cpp @@ -33,7 +33,8 @@ BOOST_AUTO_TEST_SUITE(whisper) BOOST_AUTO_TEST_CASE(topic) { cnote << "Testing Whisper..."; -// g_logVerbosity = 0; + auto oldLogVerbosity = g_logVerbosity; + g_logVerbosity = 0; bool started = false; unsigned result = 0; @@ -81,7 +82,7 @@ BOOST_AUTO_TEST_CASE(topic) } listener.join(); -// g_logVerbosity = 0; + g_logVerbosity = oldLogVerbosity; BOOST_REQUIRE_EQUAL(result, 1 + 9 + 25 + 49 + 81); } From ac5a0ff1fb6dce456b2a3484c322cc498dfdb51c Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 12 Dec 2014 16:04:34 +0100 Subject: [PATCH 151/277] Minor fix for execution. --- libethereum/Executive.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index c81dd7ed8..9d4e9c1e6 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -167,7 +167,7 @@ bool Executive::go(OnOpFunc const& _onOp) auto sgas = m_vm->gas(); try { - m_out = m_vm->go(*m_ext, _onOp, 0); + m_out = m_vm->go(*m_ext, _onOp); m_endGas = m_vm->gas(); m_endGas += min((m_t.gas() - m_endGas) / 2, m_ext->sub.refunds); m_logs = m_ext->sub.logs; From 056a19474066f53486afef992879a7e8fee036ce Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 12 Dec 2014 16:43:42 +0100 Subject: [PATCH 152/277] common changes --- CMakeLists.txt | 3 --- exp/CMakeLists.txt | 3 --- libdevcrypto/CMakeLists.txt | 2 +- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 98da62bdc..02e3a1a05 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -129,9 +129,6 @@ add_subdirectory(libethcore) add_subdirectory(libevm) add_subdirectory(libethereum) -# TODO is this 'TODO remove' still valid? -# add_subdirectory(libethereumx) # TODO remove - add_subdirectory(libwebthree) add_subdirectory(test) add_subdirectory(eth) diff --git a/exp/CMakeLists.txt b/exp/CMakeLists.txt index 49bbbf16b..d0aadc8ae 100644 --- a/exp/CMakeLists.txt +++ b/exp/CMakeLists.txt @@ -10,11 +10,8 @@ set(EXECUTABLE exp) add_executable(${EXECUTABLE} ${SRC_LIST}) -target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) - target_link_libraries(${EXECUTABLE} ethereum) target_link_libraries(${EXECUTABLE} p2p) -target_link_libraries(${EXECUTABLE} gmp) install( TARGETS ${EXECUTABLE} DESTINATION bin) diff --git a/libdevcrypto/CMakeLists.txt b/libdevcrypto/CMakeLists.txt index c0fa56026..20eab916a 100644 --- a/libdevcrypto/CMakeLists.txt +++ b/libdevcrypto/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_policy(SET CMP0015 OLD) +cmake_policy(SET CMP0015 NEW) # this policy was introduced in cmake 3.0 # remove if, once 3.0 will be used on unix if (${CMAKE_MAJOR_VERSION} GREATER 2) From 5e2df7fcbc8ce5a8c9dc0c84f92dcdf3243cd4c0 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 12 Dec 2014 17:17:05 +0100 Subject: [PATCH 153/277] removed duplicated, unused file --- extdep/compile/configure.bat | 111 ----------------------------------- 1 file changed, 111 deletions(-) delete mode 100644 extdep/compile/configure.bat diff --git a/extdep/compile/configure.bat b/extdep/compile/configure.bat deleted file mode 100644 index bd810938a..000000000 --- a/extdep/compile/configure.bat +++ /dev/null @@ -1,111 +0,0 @@ -::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -:: -:: Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -:: Contact: http://www.qt-project.org/legal -:: -:: This file is part of the tools applications of the Qt Toolkit. -:: -:: $QT_BEGIN_LICENSE:LGPL$ -:: Commercial License Usage -:: Licensees holding valid commercial Qt licenses may use this file in -:: accordance with the commercial license agreement provided with the -:: Software or, alternatively, in accordance with the terms contained in -:: a written agreement between you and Digia. For licensing terms and -:: conditions see http://qt.digia.com/licensing. For further information -:: use the contact form at http://qt.digia.com/contact-us. -:: -:: GNU Lesser General Public License Usage -:: Alternatively, this file may be used under the terms of the GNU Lesser -:: General Public License version 2.1 as published by the Free Software -:: Foundation and appearing in the file LICENSE.LGPL included in the -:: packaging of this file. Please review the following information to -:: ensure the GNU Lesser General Public License version 2.1 requirements -:: will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -:: -:: In addition, as a special exception, Digia gives you certain additional -:: rights. These rights are described in the Digia Qt LGPL Exception -:: version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -:: -:: GNU General Public License Usage -:: Alternatively, this file may be used under the terms of the GNU -:: General Public License version 3.0 as published by the Free Software -:: Foundation and appearing in the file LICENSE.GPL included in the -:: packaging of this file. Please review the following information to -:: ensure the GNU General Public License version 3.0 requirements will be -:: met: http://www.gnu.org/copyleft/gpl.html. -:: -:: -:: $QT_END_LICENSE$ -:: -::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: - -@echo off -set QTSRC=%~dp0 -set QTDIR=%CD% -::if not exist %QTSRC%\.gitignore goto sconf -echo Please wait while bootstrapping configure ... - -for %%C in (cl.exe icl.exe g++.exe perl.exe) do set %%C=%%~$PATH:C - -if "%perl.exe%" == "" ( - echo Perl not found in PATH. Aborting. >&2 - exit /b 1 -) -if not exist mkspecs ( - md mkspecs - if errorlevel 1 goto exit -) -perl %QTSRC%bin\syncqt.pl -minimal -module QtCore -outdir %QTDIR% %QTSRC% -if errorlevel 1 goto exit - -if not exist tools\configure ( - md tools\configure - if errorlevel 1 goto exit -) -cd tools\configure -if errorlevel 1 goto exit - -echo #### Generated by configure.bat - DO NOT EDIT! ####> Makefile -echo/>> Makefile -for /f "tokens=3 usebackq" %%V in (`findstr QT_VERSION_STR %QTSRC%\src\corelib\global\qglobal.h`) do @echo QTVERSION = %%~V>> Makefile -if not "%cl.exe%" == "" ( - echo CXX = cl>>Makefile - echo EXTRA_CXXFLAGS =>>Makefile - rem This must have a trailing space. - echo QTSRC = %QTSRC% >> Makefile - set tmpl=win32 - set make=nmake -) else if not "%icl.exe%" == "" ( - echo CXX = icl>>Makefile - echo EXTRA_CXXFLAGS = /Zc:forScope>>Makefile - rem This must have a trailing space. - echo QTSRC = %QTSRC% >> Makefile - set tmpl=win32 - set make=nmake -) else if not "%g++.exe%" == "" ( - echo CXX = g++>>Makefile - echo EXTRA_CXXFLAGS =>>Makefile - rem This must NOT have a trailing space. - echo QTSRC = %QTSRC:\=/%>> Makefile - set tmpl=mingw - set make=mingw32-make -) else ( - echo No suitable compiler found in PATH. Aborting. >&2 - cd ..\.. - exit /b 1 -) -echo/>> Makefile -type %QTSRC%tools\configure\Makefile.%tmpl% >> Makefile - -%make% -if errorlevel 1 (cd ..\.. & exit /b 1) - -cd ..\.. - -:conf -configure.exe -srcdir %QTSRC% %* -goto exit - -:sconf -%QTSRC%\configure.exe %* -:exit From a2def239d2def75a32728f9e7ab0fe2bf0b3c195 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 12 Dec 2014 17:20:44 +0100 Subject: [PATCH 154/277] common changes --- libdevcore/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libdevcore/CMakeLists.txt b/libdevcore/CMakeLists.txt index cb5f8eb3f..001c568b5 100644 --- a/libdevcore/CMakeLists.txt +++ b/libdevcore/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_policy(SET CMP0015 OLD) +cmake_policy(SET CMP0015 NEW) # this policy was introduced in cmake 3.0 # remove if, once 3.0 will be used on unix if (${CMAKE_MAJOR_VERSION} GREATER 2) From 5cc2152dd02909084a632544e2aa70bb23d31704 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 12 Dec 2014 17:22:32 +0100 Subject: [PATCH 155/277] Cleanups. --- libethereum/Executive.cpp | 25 +++++++++++++++---------- libethereum/Executive.h | 2 +- libethereum/ExtVM.h | 2 +- libethereum/State.cpp | 3 +-- libevm/VM.h | 2 +- test/state.cpp | 2 +- 6 files changed, 20 insertions(+), 16 deletions(-) diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index 9d4e9c1e6..e5a8e6b11 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -105,11 +105,13 @@ bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _sen if (_gas < g) { m_endGas = 0; - return false; + m_excepted = true; + } + else + { + m_endGas = (u256)(_gas - g); + it->second.exec(_data, bytesRef()); } - m_endGas = (u256)(_gas - g); - it->second.exec(_data, bytesRef()); - return true; } else if (m_s.addressHasCode(_codeAddress)) { @@ -169,8 +171,6 @@ bool Executive::go(OnOpFunc const& _onOp) { m_out = m_vm->go(*m_ext, _onOp); m_endGas = m_vm->gas(); - m_endGas += min((m_t.gas() - m_endGas) / 2, m_ext->sub.refunds); - m_logs = m_ext->sub.logs; if (m_isCreation) { @@ -188,11 +188,10 @@ bool Executive::go(OnOpFunc const& _onOp) { clog(StateChat) << "Safe VM Exception: " << diagnostic_information(_e); m_endGas = 0;//m_vm->gas(); + m_excepted = true; // Write state out only in the case of a non-excepted transaction. m_ext->revert(); - - m_excepted = true; } catch (Exception const& _e) { @@ -209,10 +208,10 @@ bool Executive::go(OnOpFunc const& _onOp) return true; } -u256 Executive::gas() const +/*u256 Executive::gas() const { return m_vm ? m_vm->gas() : m_endGas; -} +}*/ void Executive::finalize(OnOpFunc const&) { @@ -220,6 +219,9 @@ void Executive::finalize(OnOpFunc const&) // creation - put code in place. m_s.m_cache[m_newAddress].setCode(m_out); + // SSTORE refunds. + m_endGas += min((m_t.gas() - m_endGas) / 2, m_ext->sub.refunds); + // cnote << "Refunding" << formatBalance(m_endGas * m_ext->gasPrice) << "to origin (=" << m_endGas << "*" << formatBalance(m_ext->gasPrice) << ")"; m_s.addBalance(m_sender, m_endGas * m_t.gasPrice()); @@ -231,4 +233,7 @@ void Executive::finalize(OnOpFunc const&) if (m_ext) for (auto a: m_ext->sub.suicides) m_s.m_cache[a].kill(); + + // Logs + m_logs = m_ext->sub.logs; } diff --git a/libethereum/Executive.h b/libethereum/Executive.h index fa438f025..068439d87 100644 --- a/libethereum/Executive.h +++ b/libethereum/Executive.h @@ -59,7 +59,7 @@ public: Transaction const& t() const { return m_t; } - u256 gas() const; + u256 endGas() const { return m_endGas; } bytesConstRef out() const { return m_out; } h160 newAddress() const { return m_newAddress; } diff --git a/libethereum/ExtVM.h b/libethereum/ExtVM.h index d4937bcd5..8c04ff113 100644 --- a/libethereum/ExtVM.h +++ b/libethereum/ExtVM.h @@ -55,7 +55,7 @@ public: virtual bytes const& codeAt(Address _a) override final { return m_s.code(_a); } /// Create a new contract. - virtual h160 create(u256 _endowment, u256& io_gas, bytesConstRef _code, OnOpFunc const& _onOp = OnOpFunc()) override final + virtual h160 create(u256 _endowment, u256& io_gas, bytesConstRef _code, OnOpFunc const& _onOp = {}) override final { // Increment associated nonce for sender. m_s.noteSending(myAddress); diff --git a/libethereum/State.cpp b/libethereum/State.cpp index f2b5d7283..07dcccf2a 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -1187,10 +1187,9 @@ bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderA } e.out().copyTo(_out); - io_gas = e.gas(); + io_gas = e.endGas(); return !e.excepted(); - #else if (!_originAddress) _originAddress = _senderAddress; diff --git a/libevm/VM.h b/libevm/VM.h index 09a1f6d26..3eb330fcd 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -828,7 +828,7 @@ inline bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _st if (_ext.depth == 1024) BOOST_THROW_EXCEPTION(OutOfGas()); _ext.subBalance(value); - m_stack.push_back(_ext.call(inst == Instruction::CALL ? receiveAddress : _ext.myAddress, value, bytesConstRef(m_temp.data() + inOff, inSize), gas, bytesRef(m_temp.data() + outOff, outSize), _onOp, Address(), receiveAddress)); + m_stack.push_back(_ext.call(inst == Instruction::CALL ? receiveAddress : _ext.myAddress, value, bytesConstRef(m_temp.data() + inOff, inSize), gas, bytesRef(m_temp.data() + outOff, outSize), _onOp, {}, receiveAddress)); } else m_stack.push_back(0); diff --git a/test/state.cpp b/test/state.cpp index 07c8373e2..3fe0fe30b 100644 --- a/test/state.cpp +++ b/test/state.cpp @@ -45,7 +45,7 @@ void doStateTests(json_spirit::mValue& v, bool _fillin) { for (auto& i: v.get_obj()) { - cnote << i.first; + cerr << i.first << endl; mObject& o = i.second.get_obj(); BOOST_REQUIRE(o.count("env") > 0); From b0af628f11168b00d1f900f96844466dfcdc72f1 Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 10 Dec 2014 23:01:40 +0100 Subject: [PATCH 156/277] Calls to bare contracts. --- libsolidity/ExpressionCompiler.cpp | 122 ++++++++++++++++------------- libsolidity/ExpressionCompiler.h | 20 +++++ libsolidity/Types.cpp | 7 ++ libsolidity/Types.h | 3 +- 4 files changed, 95 insertions(+), 57 deletions(-) diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 3beb423de..add5f73be 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -194,7 +194,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) else { FunctionType const& function = dynamic_cast(*_functionCall.getExpression().getType()); - std::vector> arguments = _functionCall.getArguments(); + vector> arguments = _functionCall.getArguments(); if (asserts(arguments.size() == function.getParameterTypes().size())) BOOST_THROW_EXCEPTION(InternalCompilerError()); @@ -227,50 +227,23 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) break; } case Location::EXTERNAL: + case Location::BARE: { - unsigned dataOffset = 1; // reserve one byte for the function index - for (unsigned i = 0; i < arguments.size(); ++i) - { - arguments[i]->accept(*this); - Type const& type = *function.getParameterTypes()[i]; - appendTypeConversion(*arguments[i]->getType(), type); - unsigned const numBytes = type.getCalldataEncodedSize(); - if (numBytes == 0 || numBytes > 32) - BOOST_THROW_EXCEPTION(CompilerError() - << errinfo_sourceLocation(arguments[i]->getLocation()) - << errinfo_comment("Type " + type.toString() + " not yet supported.")); - bool const leftAligned = type.getCategory() == Type::Category::STRING; - CompilerUtils(m_context).storeInMemory(dataOffset, numBytes, leftAligned); - dataOffset += numBytes; - } - //@todo only return the first return value for now - Type const* firstType = function.getReturnParameterTypes().empty() ? nullptr : - function.getReturnParameterTypes().front().get(); - unsigned retSize = firstType ? firstType->getCalldataEncodedSize() : 0; - // CALL arguments: outSize, outOff, inSize, inOff, value, addr, gas (stack top) - m_context << u256(retSize) << u256(0) << u256(dataOffset) << u256(0) << u256(0); - _functionCall.getExpression().accept(*this); // pushes addr and function index - m_context << u256(0) << eth::Instruction::MSTORE8 - << u256(25) << eth::Instruction::GAS << eth::Instruction::SUB - << eth::Instruction::CALL - << eth::Instruction::POP; // @todo do not ignore failure indicator - if (retSize > 0) - { - bool const leftAligned = firstType->getCategory() == Type::Category::STRING; - CompilerUtils(m_context).loadFromMemory(0, retSize, leftAligned); - } + FunctionCallOptions options; + options.bare = function.getLocation() == Location::BARE; + options.obtainAddress = [&]() { _functionCall.getExpression().accept(*this); }; + appendExternalFunctionCall(function, arguments, options); break; } case Location::SEND: - m_context << u256(0) << u256(0) << u256(0) << u256(0); - arguments.front()->accept(*this); - //@todo might not be necessary - appendTypeConversion(*arguments.front()->getType(), *function.getParameterTypes().front(), true); - _functionCall.getExpression().accept(*this); - m_context << u256(25) << eth::Instruction::GAS << eth::Instruction::SUB - << eth::Instruction::CALL - << eth::Instruction::POP; + { + FunctionCallOptions options; + options.bare = true; + options.obtainAddress = [&]() { _functionCall.getExpression().accept(*this); }; + options.obtainValue = [&]() { arguments.front()->accept(*this); }; + appendExternalFunctionCall(FunctionType({}, {}, Location::EXTERNAL), {}, options); break; + } case Location::SUICIDE: arguments.front()->accept(*this); //@todo might not be necessary @@ -292,19 +265,11 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) {Location::SHA256, 2}, {Location::RIPEMD160, 3}}; u256 contractAddress = contractAddresses.find(function.getLocation())->second; - // @todo later, combine this code with external function call - for (unsigned i = 0; i < arguments.size(); ++i) - { - arguments[i]->accept(*this); - appendTypeConversion(*arguments[i]->getType(), *function.getParameterTypes()[i], true); - // @todo move this once we actually use memory - CompilerUtils(m_context).storeInMemory(i * 32); - } - m_context << u256(32) << u256(0) << u256(arguments.size() * 32) << u256(0) << u256(0) - << contractAddress << u256(500) //@todo determine actual gas requirement - << eth::Instruction::CALL - << eth::Instruction::POP; - CompilerUtils(m_context).loadFromMemory(0); + FunctionCallOptions options; + options.bare = true; + options.obtainAddress = [&]() { m_context << contractAddress; }; + options.packDensely = false; + appendExternalFunctionCall(function, arguments, options); break; } default: @@ -326,11 +291,9 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) IntegerType(0, IntegerType::Modifier::ADDRESS), true); m_context << eth::Instruction::BALANCE; } - else if (member == "send") - { + else if (member == "send" || member.substr(0, 4) == "call") appendTypeConversion(*_memberAccess.getExpression().getType(), IntegerType(0, IntegerType::Modifier::ADDRESS), true); - } else BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid member access to integer.")); break; @@ -587,6 +550,53 @@ void ExpressionCompiler::appendHighBitsCleanup(IntegerType const& _typeOnStack) m_context << ((u256(1) << _typeOnStack.getNumBits()) - 1) << eth::Instruction::AND; } +void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functionType, + vector> const& _arguments, + FunctionCallOptions const& _options) +{ + if (asserts(_arguments.size() == _functionType.getParameterTypes().size())) + BOOST_THROW_EXCEPTION(InternalCompilerError()); + + unsigned dataOffset = _options.bare ? 0 : 1; // reserve one byte for the function index + for (unsigned i = 0; i < _arguments.size(); ++i) + { + _arguments[i]->accept(*this); + Type const& type = *_functionType.getParameterTypes()[i]; + appendTypeConversion(*_arguments[i]->getType(), type); + unsigned const numBytes = _options.packDensely ? type.getCalldataEncodedSize() : 32; + if (numBytes == 0 || numBytes > 32) + BOOST_THROW_EXCEPTION(CompilerError() + << errinfo_sourceLocation(_arguments[i]->getLocation()) + << errinfo_comment("Type " + type.toString() + " not yet supported.")); + bool const leftAligned = type.getCategory() == Type::Category::STRING; + CompilerUtils(m_context).storeInMemory(dataOffset, numBytes, leftAligned); + dataOffset += numBytes; + } + //@todo only return the first return value for now + Type const* firstType = _functionType.getReturnParameterTypes().empty() ? nullptr : + _functionType.getReturnParameterTypes().front().get(); + unsigned retSize = firstType ? firstType->getCalldataEncodedSize() : 0; + if (!_options.packDensely && retSize > 0) + retSize = 32; + // CALL arguments: outSize, outOff, inSize, inOff, value, addr, gas (stack top) + m_context << u256(retSize) << u256(0) << u256(dataOffset) << u256(0); + if (_options.obtainValue) + _options.obtainValue(); + else + m_context << u256(0); + _options.obtainAddress(); + if (!_options.bare) + m_context << u256(0) << eth::Instruction::MSTORE8; + m_context << u256(25) << eth::Instruction::GAS << eth::Instruction::SUB + << eth::Instruction::CALL + << eth::Instruction::POP; // @todo do not ignore failure indicator + if (retSize > 0) + { + bool const leftAligned = firstType->getCategory() == Type::Category::STRING; + CompilerUtils(m_context).loadFromMemory(0, retSize, leftAligned); + } +} + ExpressionCompiler::LValue::LValue(CompilerContext& _compilerContext, LValueType _type, Type const& _dataType, unsigned _baseStackOffset): m_context(&_compilerContext), m_type(_type), m_baseStackOffset(_baseStackOffset), diff --git a/libsolidity/ExpressionCompiler.h b/libsolidity/ExpressionCompiler.h index c0b173d46..0bba211ce 100644 --- a/libsolidity/ExpressionCompiler.h +++ b/libsolidity/ExpressionCompiler.h @@ -20,6 +20,7 @@ * Solidity AST to EVM bytecode compiler for expressions. */ +#include #include #include #include @@ -83,6 +84,25 @@ private: //// Appends code that cleans higher-order bits for integer types. void appendHighBitsCleanup(IntegerType const& _typeOnStack); + /// Additional options used in appendExternalFunctionCall. + struct FunctionCallOptions + { + FunctionCallOptions() {} + /// Invoked to copy the address to the stack + std::function obtainAddress; + /// Invoked to copy the ethe value to the stack (if not specified, value is 0). + std::function obtainValue; + /// If true, do not prepend function index to call data + bool bare = false; + /// If false, use calling convention that all arguments and return values are packed as + /// 32 byte values with padding. + bool packDensely = true; + }; + + /// Appends code to call a function of the given type with the given arguments. + void appendExternalFunctionCall(FunctionType const& _functionType, std::vector> const& _arguments, + FunctionCallOptions const& _options = FunctionCallOptions()); + /** * Helper class to store and retrieve lvalues to and from various locations. * All types except STACK store a reference in a slot on the stack, STACK just diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 00e530c3f..a0a809b9b 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -194,6 +194,11 @@ u256 IntegerType::literalValue(Literal const& _literal) const const MemberList IntegerType::AddressMemberList = MemberList({{"balance", make_shared(256)}, + {"callstring32", make_shared(TypePointers({make_shared(32)}), + TypePointers(), FunctionType::Location::BARE)}, + {"callstring32string32", make_shared(TypePointers({make_shared(32), + make_shared(32)}), + TypePointers(), FunctionType::Location::BARE)}, {"send", make_shared(TypePointers({make_shared(256)}), TypePointers(), FunctionType::Location::SEND)}}); @@ -424,6 +429,8 @@ unsigned FunctionType::getSizeOnStack() const return 1; case Location::EXTERNAL: return 2; + case Location::BARE: + return 1; default: return 0; } diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 8e93bd31d..807e60c74 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -296,8 +296,9 @@ class FunctionType: public Type public: /// The meaning of the value(s) on the stack referencing the function: /// INTERNAL: jump tag, EXTERNAL: contract address + function index, + /// BARE: contract address (non-abi contract call) /// OTHERS: special virtual function, nothing on the stack - enum class Location { INTERNAL, EXTERNAL, SEND, SHA3, SUICIDE, ECRECOVER, SHA256, RIPEMD160 }; + enum class Location { INTERNAL, EXTERNAL, SEND, SHA3, SUICIDE, ECRECOVER, SHA256, RIPEMD160, BARE }; virtual Category getCategory() const override { return Category::FUNCTION; } explicit FunctionType(FunctionDefinition const& _function, bool _isInternal = true); From ebd8f5bfa5d57ea6b5835cee9e921b8a819a6444 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 12 Dec 2014 17:41:44 +0100 Subject: [PATCH 157/277] 04 changed to 03 --- cmake/EthCompilerSettings.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index 8cf8b51b4..24252cc0b 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -6,7 +6,7 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB -fPIC") set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DETH_DEBUG") set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE") - set(CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG -DETH_RELEASE") + set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -DETH_RELEASE") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_DEBUG") set(ETH_SHARED 1) @@ -21,7 +21,7 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB -fPIC") set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DETH_DEBUG") set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE") - set(CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG -DETH_RELEASE") + set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -DETH_RELEASE") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_DEBUG") set(ETH_SHARED 1) From 0305a8480feb7283117a403960a7ac6d05ba02fb Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 12 Dec 2014 17:52:33 +0100 Subject: [PATCH 158/277] fixed leak in q_webthreeconnector in mainwin --- alethzero/MainWin.cpp | 3 +-- alethzero/MainWin.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 1b26b3dc2..db1b5dd10 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -153,8 +153,7 @@ Main::Main(QWidget *parent) : m_webThree.reset(new WebThreeDirect(string("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir() + "/AlethZero", false, {"eth", "shh"})); - // w3stubserver, on dealloc, deletes m_qwebConnector - m_qwebConnector = new QWebThreeConnector(); // owned by WebThreeStubServer + m_qwebConnector.reset(new QWebThreeConnector()); m_server.reset(new OurWebThreeStubServer(*m_qwebConnector, *web3(), keysAsVector(m_myKeys))); connect(&*m_server, SIGNAL(onNewId(QString)), SLOT(addNewId(QString))); m_server->setIdentities(keysAsVector(owned())); diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 50b9df413..2582aa23d 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -256,7 +256,7 @@ private: QString m_logHistory; bool m_logChanged = true; - QWebThreeConnector* m_qwebConnector; + std::unique_ptr m_qwebConnector; std::unique_ptr m_server; QWebThree* m_qweb = nullptr; }; From 921d816a29beba5495f4aa229d476ec65250df0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Fri, 12 Dec 2014 18:53:57 +0100 Subject: [PATCH 159/277] Update Visual Studio projects --- windows/LibEthereum.vcxproj | 7 ++++--- windows/LibEthereum.vcxproj.filters | 12 ++++++++++++ windows/LibEvmJit.vcxproj | 2 ++ windows/LibEvmJit.vcxproj.filters | 2 ++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/windows/LibEthereum.vcxproj b/windows/LibEthereum.vcxproj index 66efe7dc2..b4624f962 100644 --- a/windows/LibEthereum.vcxproj +++ b/windows/LibEthereum.vcxproj @@ -125,7 +125,6 @@ - @@ -146,7 +145,7 @@ true true - + @@ -170,6 +169,7 @@ true true + true true @@ -343,7 +343,6 @@ - @@ -372,6 +371,7 @@ true + @@ -408,6 +408,7 @@ true true + true true diff --git a/windows/LibEthereum.vcxproj.filters b/windows/LibEthereum.vcxproj.filters index 76201d823..e70393706 100644 --- a/windows/LibEthereum.vcxproj.filters +++ b/windows/LibEthereum.vcxproj.filters @@ -198,6 +198,12 @@ + + libevm + + + libp2p + @@ -437,6 +443,12 @@ libevm + + libevm + + + libp2p + diff --git a/windows/LibEvmJit.vcxproj b/windows/LibEvmJit.vcxproj index 077757aab..c3b1f65a7 100644 --- a/windows/LibEvmJit.vcxproj +++ b/windows/LibEvmJit.vcxproj @@ -130,6 +130,7 @@ + @@ -147,6 +148,7 @@ + diff --git a/windows/LibEvmJit.vcxproj.filters b/windows/LibEvmJit.vcxproj.filters index 06f1ed308..88dc8d329 100644 --- a/windows/LibEvmJit.vcxproj.filters +++ b/windows/LibEvmJit.vcxproj.filters @@ -16,6 +16,7 @@ + @@ -35,6 +36,7 @@ + From 2eaed59cd4a003c2f8c2e404893067f3eb73cb9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Fri, 12 Dec 2014 18:54:39 +0100 Subject: [PATCH 160/277] Fix dev::contents function on MSVC --- libdevcore/CommonIO.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libdevcore/CommonIO.cpp b/libdevcore/CommonIO.cpp index 8fc4fedb3..ec8ca605c 100644 --- a/libdevcore/CommonIO.cpp +++ b/libdevcore/CommonIO.cpp @@ -65,6 +65,8 @@ bytes dev::contents(std::string const& _file) // get length of file: is.seekg (0, is.end); streamoff length = is.tellg(); + if (length == 0) // return early, MSVC does not like reading 0 bytes + return {}; is.seekg (0, is.beg); bytes ret(length); is.read((char*)ret.data(), length); From daa6b8f84951978d08458306cafa12a1d0f2ec72 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 12 Dec 2014 19:44:09 +0100 Subject: [PATCH 161/277] Refactor state to use executive for calls. --- libethereum/Executive.cpp | 11 ++++++----- libethereum/Executive.h | 3 ++- libethereum/State.cpp | 32 ++++++++++++-------------------- libethereum/State.h | 2 +- 4 files changed, 21 insertions(+), 27 deletions(-) diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index e5a8e6b11..d568996c3 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -98,7 +98,7 @@ bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _sen // cnote << "Transferring" << formatBalance(_value) << "to receiver."; m_s.addBalance(_receiveAddress, _value); - auto it = !(_receiveAddress & ~h160(0xffffffff)) ? State::precompiled().find((unsigned)(u160)_receiveAddress) : State::precompiled().end(); + auto it = !(_codeAddress & ~h160(0xffffffff)) ? State::precompiled().find((unsigned)(u160)_codeAddress) : State::precompiled().end(); if (it != State::precompiled().end()) { bigint g = it->second.gas(_data); @@ -110,13 +110,14 @@ bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _sen else { m_endGas = (u256)(_gas - g); - it->second.exec(_data, bytesRef()); + m_precompiledOut = it->second.exec(_data); + m_out = &m_precompiledOut; } } else if (m_s.addressHasCode(_codeAddress)) { m_vm = VMFactory::create(_gas); - bytes const& c = m_s.code(_receiveAddress); + bytes const& c = m_s.code(_codeAddress); m_ext = make_shared(m_s, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &c, m_depth); } else @@ -166,7 +167,7 @@ bool Executive::go(OnOpFunc const& _onOp) if (m_vm) { boost::timer t; - auto sgas = m_vm->gas(); +// auto sgas = m_vm->gas(); try { m_out = m_vm->go(*m_ext, _onOp); @@ -203,7 +204,7 @@ bool Executive::go(OnOpFunc const& _onOp) // TODO: AUDIT: check that this can never reasonably happen. Consider what to do if it does. cwarn << "Unexpected std::exception in VM. This is probably unrecoverable. " << _e.what(); } - cnote << "VM took:" << t.elapsed() << "; gas used: " << (sgas - m_endGas); +// cnote << "VM took:" << t.elapsed() << "; gas used: " << (sgas - m_endGas); } return true; } diff --git a/libethereum/Executive.h b/libethereum/Executive.h index 068439d87..d6de1491e 100644 --- a/libethereum/Executive.h +++ b/libethereum/Executive.h @@ -74,7 +74,8 @@ private: State& m_s; std::shared_ptr m_ext; std::unique_ptr m_vm; - bytesConstRef m_out; + bytes m_precompiledOut; ///< Used for the output when there is no VM for a contract (i.e. precompiled). + bytesConstRef m_out; ///< Holds the copyable output. Address m_newAddress; Transaction m_t; diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 07dcccf2a..65f3cdeca 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -42,7 +42,7 @@ using namespace dev::eth; static const u256 c_blockReward = 1500 * finney; -void ecrecoverCode(bytesConstRef _in, bytesRef _out) +bytes ecrecoverCode(bytesConstRef _in) { struct inType { @@ -54,38 +54,35 @@ void ecrecoverCode(bytesConstRef _in, bytesRef _out) memcpy(&in, _in.data(), min(_in.size(), sizeof(in))); - memset(_out.data(), 0, _out.size()); + h256 ret; + if ((u256)in.v > 28) - return; + return ret.asBytes(); SignatureStruct sig{in.r, in.s, (byte)((int)(u256)in.v - 27)}; if (!sig.isValid()) - return; + return ret.asBytes(); - h256 ret; byte pubkey[65]; int pubkeylen = 65; secp256k1_start(); if (secp256k1_ecdsa_recover_compact(in.hash.data(), 32, in.r.data(), pubkey, &pubkeylen, 0, (int)(u256)in.v - 27)) ret = dev::sha3(bytesConstRef(&(pubkey[1]), 64)); - memset(ret.data(), 0, 12); - memcpy(_out.data(), &ret, min(_out.size(), sizeof(ret))); + return ret.asBytes(); } -void sha256Code(bytesConstRef _in, bytesRef _out) +bytes sha256Code(bytesConstRef _in) { h256 ret; sha256(_in, bytesRef(ret.data(), 32)); - memcpy(_out.data(), &ret, min(_out.size(), sizeof(ret))); + return ret.asBytes(); } -void ripemd160Code(bytesConstRef _in, bytesRef _out) +bytes ripemd160Code(bytesConstRef _in) { h256 ret; ripemd160(_in, bytesRef(ret.data(), 32)); - memset(_out.data(), 0, std::min(12, _out.size())); - if (_out.size() > 12) - memcpy(_out.data() + 12, &ret, min(_out.size() - 12, sizeof(ret))); + return ret.asBytes(); } const std::map State::c_precompiled = @@ -1176,24 +1173,19 @@ u256 State::execute(bytesConstRef _rlp, bytes* o_output, bool _commit) bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256& io_gas, bytesRef _out, Address _originAddress, SubState& io_sub, OnOpFunc const& _onOp, unsigned _level) { -#if 0 +#if 1 // TODO: TEST TEST TEST!!! Executive e(*this, _level); - if (!e.call(_receiveAddress, _codeAddress, _senderAddress, _value, _gasPrice, _data, io_gas, _originAddress)) { e.go(_onOp); io_sub += e.ext().sub; } - - e.out().copyTo(_out); io_gas = e.endGas(); + e.out().copyTo(_out); return !e.excepted(); #else - if (!_originAddress) - _originAddress = _senderAddress; - // cnote << "Transferring" << formatBalance(_value) << "to receiver."; addBalance(_receiveAddress, _value); diff --git a/libethereum/State.h b/libethereum/State.h index dd83a83ee..744f82e10 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -55,7 +55,7 @@ struct StateDetail: public LogChannel { static const char* name() { return "/S/" struct PrecompiledAddress { std::function gas; - std::function exec; + std::function exec; }; /** From 5412dbb9e8ba7ad13f21bebe0cb088322b07a6e2 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 12 Dec 2014 20:38:49 +0100 Subject: [PATCH 162/277] Remove old code, refactor State::call, State::create to use Executive. --- libethereum/Executive.cpp | 5 +- libethereum/Executive.h | 2 +- libethereum/State.cpp | 120 ++++---------------------------------- 3 files changed, 14 insertions(+), 113 deletions(-) diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index d568996c3..deb3da33e 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -179,6 +179,7 @@ bool Executive::go(OnOpFunc const& _onOp) m_endGas -= m_out.size() * c_createDataGas; else m_out.reset(); + m_s.m_cache[m_newAddress].setCode(m_out); } } catch (StepsDone const&) @@ -216,10 +217,6 @@ bool Executive::go(OnOpFunc const& _onOp) void Executive::finalize(OnOpFunc const&) { - if (m_t.isCreation() && !m_ext->sub.suicides.count(m_newAddress)) - // creation - put code in place. - m_s.m_cache[m_newAddress].setCode(m_out); - // SSTORE refunds. m_endGas += min((m_t.gas() - m_endGas) / 2, m_ext->sub.refunds); diff --git a/libethereum/Executive.h b/libethereum/Executive.h index d6de1491e..c5baada1d 100644 --- a/libethereum/Executive.h +++ b/libethereum/Executive.h @@ -67,8 +67,8 @@ public: bool excepted() const { return m_excepted; } VMFace const& vm() const { return *m_vm; } - State const& state() const { return m_s; } ExtVM const& ext() const { return *m_ext; } + State const& state() const { return m_s; } private: State& m_s; diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 65f3cdeca..bad41d0a5 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -73,16 +73,16 @@ bytes ecrecoverCode(bytesConstRef _in) bytes sha256Code(bytesConstRef _in) { - h256 ret; - sha256(_in, bytesRef(ret.data(), 32)); - return ret.asBytes(); + bytes ret(32); + sha256(_in, &ret); + return ret; } bytes ripemd160Code(bytesConstRef _in) { - h256 ret; - ripemd160(_in, bytesRef(ret.data(), 32)); - return ret.asBytes(); + bytes ret(32); + ripemd160(_in, &ret); + return ret; } const std::map State::c_precompiled = @@ -1173,8 +1173,6 @@ u256 State::execute(bytesConstRef _rlp, bytes* o_output, bool _commit) bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256& io_gas, bytesRef _out, Address _originAddress, SubState& io_sub, OnOpFunc const& _onOp, unsigned _level) { -#if 1 - // TODO: TEST TEST TEST!!! Executive e(*this, _level); if (!e.call(_receiveAddress, _codeAddress, _senderAddress, _value, _gasPrice, _data, io_gas, _originAddress)) { @@ -1185,112 +1183,18 @@ bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderA e.out().copyTo(_out); return !e.excepted(); -#else -// cnote << "Transferring" << formatBalance(_value) << "to receiver."; - addBalance(_receiveAddress, _value); - - auto it = !(_codeAddress & ~h160(0xffffffff)) ? c_precompiled.find((unsigned)(u160)_codeAddress) : c_precompiled.end(); - if (it != c_precompiled.end()) - { - bigint g = it->second.gas(_data); - if (io_gas < g) - { - io_gas = 0; - return false; - } - - io_gas -= (u256)g; - it->second.exec(_data, _out); - } - else if (addressHasCode(_codeAddress)) - { - auto vm = VMFactory::create(io_gas); - ExtVM evm(*this, _receiveAddress, _senderAddress, _originAddress, _value, _gasPrice, _data, &code(_codeAddress), _level); - try - { - auto out = vm->go(evm, _onOp); - memcpy(_out.data(), out.data(), std::min(out.size(), _out.size())); - io_sub += evm.sub; - io_gas = vm->gas(); - // Write state out only in the case of a non-excepted transaction. - return true; - } - catch (VMException const& _e) - { - clog(StateChat) << "Safe VM Exception: " << diagnostic_information(_e); - evm.revert(); - io_gas = 0; - return false; - } - catch (Exception const& _e) - { - cwarn << "Unexpected exception in VM: " << diagnostic_information(_e) << ". This is exceptionally bad."; - // TODO: use fallback known-safe VM. - // AUDIT: THIS SHOULD NEVER HAPPEN! PROVE IT! - throw; - } - catch (std::exception const& _e) - { - cwarn << "Unexpected exception in VM: " << _e.what() << ". This is exceptionally bad."; - // TODO: use fallback known-safe VM. - // AUDIT: THIS SHOULD NEVER HAPPEN! PROVE IT! - throw; - } - } - return true; -#endif } h160 State::create(Address _sender, u256 _endowment, u256 _gasPrice, u256& io_gas, bytesConstRef _code, Address _origin, SubState& io_sub, OnOpFunc const& _onOp, unsigned _level) { - if (!_origin) - _origin = _sender; - - Address newAddress = right160(sha3(rlpList(_sender, transactionsFrom(_sender) - 1))); - - // Set up new account... - m_cache[newAddress] = Account(balance(newAddress) + _endowment, Account::ContractConception); - - // Execute init code. - auto vm = VMFactory::create(io_gas); - ExtVM evm(*this, newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _code, _level); - bytesConstRef out; - - try - { - out = vm->go(evm, _onOp); - io_sub += evm.sub; - io_gas = vm->gas(); - - if (out.size() * c_createDataGas <= io_gas) - io_gas -= out.size() * c_createDataGas; - else - out.reset(); - - // Set code. - if (!evm.sub.suicides.count(newAddress)) - m_cache[newAddress].setCode(out); - } - catch (VMException const& _e) - { - clog(StateChat) << "Safe VM Exception: " << diagnostic_information(_e); - evm.revert(); - io_gas = 0; - } - catch (Exception const& _e) - { - // TODO: AUDIT: check that this can never reasonably happen. Consider what to do if it does. - cwarn << "Unexpected exception in VM. There may be a bug in this implementation. " << diagnostic_information(_e); - throw; - } - catch (std::exception const& _e) + Executive e(*this, _level); + if (!e.create(_sender, _endowment, _gasPrice, io_gas, _code, _origin)) { - // TODO: AUDIT: check that this can never reasonably happen. Consider what to do if it does. - cwarn << "Unexpected std::exception in VM. This is probably unrecoverable. " << _e.what(); - throw; + e.go(_onOp); + io_sub += e.ext().sub; } - - return newAddress; + io_gas = e.endGas(); + return e.newAddress(); } State State::fromPending(unsigned _i) const From aa25784764e2bb91626bd4d8fc758072b207c5dc Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 12 Dec 2014 20:44:36 +0100 Subject: [PATCH 163/277] Fix alignment of RIPEMD160. --- libethereum/State.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libethereum/State.cpp b/libethereum/State.cpp index bad41d0a5..7ca973e05 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -82,6 +82,9 @@ bytes ripemd160Code(bytesConstRef _in) { bytes ret(32); ripemd160(_in, &ret); + // leaves the 20-byte hash left-aligned. we want it right-aligned: + memmove(ret.data() + 12, ret.data(), 20); + memset(ret.data(), 0, 12); return ret; } From ede878cefde5b6b77bf11d39203e5092238a9832 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 12 Dec 2014 20:49:28 +0100 Subject: [PATCH 164/277] Style fix. --- test/TestHelper.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index 1201cfee2..ff8a0d40c 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -331,10 +331,8 @@ void checkStorage(map _expectedStore, map _resultStore, } for (auto&& resultStorePair : _resultStore) - { if (!_expectedStore.count(resultStorePair.first)) BOOST_ERROR(_expectedAddr << ": unexpected store key " << resultStorePair.first); - } } void checkLog(LogEntries _resultLogs, LogEntries _expectedLogs) From a4bf3c645cba4697bc42df5f573747df911b82b4 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 12 Dec 2014 21:02:47 +0100 Subject: [PATCH 165/277] Finally! Remove two horrible, nasty, lingering, confusing, hacky calls in State. --- libethereum/ExtVM.cpp | 36 ++++++++++++++++++++++++++++++++++-- libethereum/ExtVM.h | 12 ++---------- libethereum/State.cpp | 26 -------------------------- libethereum/State.h | 11 ----------- 4 files changed, 36 insertions(+), 49 deletions(-) diff --git a/libethereum/ExtVM.cpp b/libethereum/ExtVM.cpp index 4c343c162..fcd703b25 100644 --- a/libethereum/ExtVM.cpp +++ b/libethereum/ExtVM.cpp @@ -21,5 +21,37 @@ #include "ExtVM.h" -#pragma GCC diagnostic ignored "-Wunused-variable" -namespace { char dummy; }; +#include "Executive.h" +using namespace std; +using namespace dev; +using namespace dev::eth; + +bool ExtVM::call(Address _receiveAddress, u256 _txValue, bytesConstRef _txData, u256& io_gas, bytesRef _out, OnOpFunc const& _onOp, Address _myAddressOverride, Address _codeAddressOverride) +{ + Executive e(m_s, depth + 1); + if (!e.call(_receiveAddress, _codeAddressOverride ? _codeAddressOverride : _receiveAddress, _myAddressOverride ? _myAddressOverride : myAddress, _txValue, gasPrice, _txData, io_gas, origin)) + { + e.go(_onOp); + sub += e.ext().sub; + } + io_gas = e.endGas(); + e.out().copyTo(_out); + + return !e.excepted(); +} + +h160 ExtVM::create(u256 _endowment, u256& io_gas, bytesConstRef _code, OnOpFunc const& _onOp) +{ + // Increment associated nonce for sender. + m_s.noteSending(myAddress); + + Executive e(m_s, depth + 1); + if (!e.create(myAddress, _endowment, gasPrice, io_gas, _code, origin)) + { + e.go(_onOp); + sub += e.ext().sub; + } + io_gas = e.endGas(); + return e.newAddress(); +} + diff --git a/libethereum/ExtVM.h b/libethereum/ExtVM.h index 8c04ff113..9699a68ad 100644 --- a/libethereum/ExtVM.h +++ b/libethereum/ExtVM.h @@ -55,18 +55,10 @@ public: virtual bytes const& codeAt(Address _a) override final { return m_s.code(_a); } /// Create a new contract. - virtual h160 create(u256 _endowment, u256& io_gas, bytesConstRef _code, OnOpFunc const& _onOp = {}) override final - { - // Increment associated nonce for sender. - m_s.noteSending(myAddress); - return m_s.create(myAddress, _endowment, gasPrice, io_gas, _code, origin, sub, _onOp, depth + 1); - } + virtual h160 create(u256 _endowment, u256& io_gas, bytesConstRef _code, OnOpFunc const& _onOp = {}) override final; /// Create a new message call. Leave _myAddressOverride as the default to use the present address as caller. - virtual bool call(Address _receiveAddress, u256 _txValue, bytesConstRef _txData, u256& io_gas, bytesRef _out, OnOpFunc const& _onOp = {}, Address _myAddressOverride = {}, Address _codeAddressOverride = {}) override final - { - return m_s.call(_receiveAddress, _codeAddressOverride ? _codeAddressOverride : _receiveAddress, _myAddressOverride ? _myAddressOverride : myAddress, _txValue, gasPrice, _txData, io_gas, _out, origin, sub, _onOp, depth + 1); - } + virtual bool call(Address _receiveAddress, u256 _txValue, bytesConstRef _txData, u256& io_gas, bytesRef _out, OnOpFunc const& _onOp = {}, Address _myAddressOverride = {}, Address _codeAddressOverride = {}) override final; /// Read address's balance. virtual u256 balance(Address _a) override final { return m_s.balance(_a); } diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 7ca973e05..bd5c770cf 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -1174,32 +1174,6 @@ u256 State::execute(bytesConstRef _rlp, bytes* o_output, bool _commit) return e.gasUsed(); } -bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256& io_gas, bytesRef _out, Address _originAddress, SubState& io_sub, OnOpFunc const& _onOp, unsigned _level) -{ - Executive e(*this, _level); - if (!e.call(_receiveAddress, _codeAddress, _senderAddress, _value, _gasPrice, _data, io_gas, _originAddress)) - { - e.go(_onOp); - io_sub += e.ext().sub; - } - io_gas = e.endGas(); - e.out().copyTo(_out); - - return !e.excepted(); -} - -h160 State::create(Address _sender, u256 _endowment, u256 _gasPrice, u256& io_gas, bytesConstRef _code, Address _origin, SubState& io_sub, OnOpFunc const& _onOp, unsigned _level) -{ - Executive e(*this, _level); - if (!e.create(_sender, _endowment, _gasPrice, io_gas, _code, _origin)) - { - e.go(_onOp); - io_sub += e.ext().sub; - } - io_gas = e.endGas(); - return e.newAddress(); -} - State State::fromPending(unsigned _i) const { State ret = *this; diff --git a/libethereum/State.h b/libethereum/State.h index 744f82e10..afa1f1d2c 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -272,17 +272,6 @@ private: /// Throws on failure. u256 enact(bytesConstRef _block, BlockChain const* _bc = nullptr, bool _checkNonce = true); - // Two priviledged entry points for the VM (these don't get added to the Transaction lists): - // We assume all instrinsic fees are paid up before this point. - - /// Execute a contract-creation transaction. - h160 create(Address _txSender, u256 _endowment, u256 _gasPrice, u256& io_gas, bytesConstRef _code, Address _originAddress, SubState& io_sub, OnOpFunc const& _onOp, unsigned _level); - - /// Execute a call. - /// @a _gas points to the amount of gas to use for the call, and will lower it accordingly. - /// @returns false if the call ran out of gas before completion. true otherwise. - bool call(Address _myAddress, Address _codeAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256& io_gas, bytesRef _out, Address _originAddress, SubState& io_sub, OnOpFunc const& _onOp, unsigned _level); - /// Sets m_currentBlock to a clean state, (i.e. no change from m_previousBlock). void resetCurrent(); From d36a2fa5098f512be7cbe3fc3869eb6dd919569f Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Fri, 12 Dec 2014 21:21:18 +0100 Subject: [PATCH 166/277] Fix import state for state tests Conflicts: test/TestHelper.cpp --- test/TestHelper.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index ff8a0d40c..e8940cc7a 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -109,9 +109,6 @@ void ImportTest::importState(json_spirit::mObject& _o, State& _state) Address address = Address(i.first); - for (auto const& j: o["storage"].get_obj()) - _state.setStorage(address, toInt(j.first), toInt(j.second)); - bytes code = importCode(o); if (code.size()) @@ -122,6 +119,9 @@ void ImportTest::importState(json_spirit::mObject& _o, State& _state) else _state.m_cache[address] = Account(toInt(o["balance"]), Account::NormalCreation); + for (auto const& j: o["storage"].get_obj()) + _state.setStorage(address, toInt(j.first), toInt(j.second)); + for(int i=0; i _expectedStore, map _resultStore, BOOST_CHECK_MESSAGE(expectedStoreValue == resultStoreValue, _expectedAddr << ": store[" << expectedStoreKey << "] = " << resultStoreValue << ", expected " << expectedStoreValue); } } - + BOOST_CHECK_EQUAL(_resultStore.size(), _expectedStore.size()); for (auto&& resultStorePair : _resultStore) if (!_expectedStore.count(resultStorePair.first)) BOOST_ERROR(_expectedAddr << ": unexpected store key " << resultStorePair.first); From 45807bff5ee93a291222d86d0670d6c4e096f153 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Fri, 12 Dec 2014 21:45:10 +0100 Subject: [PATCH 167/277] set first 12 bytes to zero in ecrecover --- libethereum/State.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libethereum/State.cpp b/libethereum/State.cpp index bd5c770cf..30290c315 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -67,7 +67,7 @@ bytes ecrecoverCode(bytesConstRef _in) secp256k1_start(); if (secp256k1_ecdsa_recover_compact(in.hash.data(), 32, in.r.data(), pubkey, &pubkeylen, 0, (int)(u256)in.v - 27)) ret = dev::sha3(bytesConstRef(&(pubkey[1]), 64)); - + memset(ret.data(), 0, 12); return ret.asBytes(); } From 28556f42ecb9142eaa7afce3edee03f5b4e7cf58 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 12 Dec 2014 21:51:54 +0100 Subject: [PATCH 168/277] Remove unneeded files. --- libethereum/Manifest.cpp | 0 libethereum/Manifest.h | 0 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 libethereum/Manifest.cpp delete mode 100644 libethereum/Manifest.h diff --git a/libethereum/Manifest.cpp b/libethereum/Manifest.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/libethereum/Manifest.h b/libethereum/Manifest.h deleted file mode 100644 index e69de29bb..000000000 From 82d29fa979dffabd9a76ddb1c7b0ae513404c251 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 12 Dec 2014 21:54:29 +0100 Subject: [PATCH 169/277] Rename headers. --- alethzero/MainWin.h | 1 - libethereum/BlockDetails.h | 1 - libethereum/Client.h | 4 +- libethereum/Interface.h | 7 +-- libethereum/MessageFilter.cpp | 81 -------------------------------- libethereum/MessageFilter.h | 69 --------------------------- libethereum/TransactionReceipt.h | 1 - 7 files changed, 2 insertions(+), 162 deletions(-) delete mode 100644 libethereum/MessageFilter.cpp delete mode 100644 libethereum/MessageFilter.h diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index fffc5843f..f2d632cd4 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -44,7 +44,6 @@ class Main; namespace dev { namespace eth { class Client; class State; -class MessageFilter; }} class QQuickView; diff --git a/libethereum/BlockDetails.h b/libethereum/BlockDetails.h index 2fd0d3048..bbfd48e56 100644 --- a/libethereum/BlockDetails.h +++ b/libethereum/BlockDetails.h @@ -28,7 +28,6 @@ #include #include -#include "Manifest.h" #include "TransactionReceipt.h" namespace ldb = leveldb; diff --git a/libethereum/Client.h b/libethereum/Client.h index 283251e24..477ea43e5 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -37,7 +37,7 @@ #include "State.h" #include "CommonNet.h" #include "PastMessage.h" -#include "MessageFilter.h" +#include "LogFilter.h" #include "Miner.h" #include "Interface.h" @@ -79,8 +79,6 @@ static const int GenesisBlock = INT_MIN; struct InstalledFilter { -// InstalledFilter(MessageFilter const& _f): filter(_f) {} -// MessageFilter filter; InstalledFilter(LogFilter const& _f): filter(_f) {} LogFilter filter; diff --git a/libethereum/Interface.h b/libethereum/Interface.h index d598e1f9b..28ac26819 100644 --- a/libethereum/Interface.h +++ b/libethereum/Interface.h @@ -26,7 +26,7 @@ #include #include #include -#include "MessageFilter.h" +#include "LogFilter.h" #include "Transaction.h" #include "AccountDiff.h" #include "BlockDetails.h" @@ -84,11 +84,6 @@ public: virtual bytes codeAt(Address _a, int _block) const = 0; virtual std::map storageAt(Address _a, int _block) const = 0; -// // [MESSAGE API] -// -// virtual PastMessages messages(unsigned _watchId) const = 0; -// virtual PastMessages messages(MessageFilter const& _filter) const = 0; - // [LOGS API] virtual LogEntries logs(unsigned _watchId) const = 0; diff --git a/libethereum/MessageFilter.cpp b/libethereum/MessageFilter.cpp deleted file mode 100644 index f44587620..000000000 --- a/libethereum/MessageFilter.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - This file is part of cpp-ethereum. - - cpp-ethereum 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. - - cpp-ethereum 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 cpp-ethereum. If not, see . -*/ -/** @file MessageFilter.cpp - * @author Gav Wood - * @date 2014 - */ - -#include "MessageFilter.h" - -#include -#include "State.h" -using namespace std; -using namespace dev; -using namespace dev::eth; - -void LogFilter::streamRLP(RLPStream& _s) const -{ - _s.appendList(6) << m_addresses << m_topics << m_earliest << m_latest << m_max << m_skip; -} - -h256 LogFilter::sha3() const -{ - RLPStream s; - streamRLP(s); - return dev::sha3(s.out()); -} - -bool LogFilter::matches(LogBloom _bloom) const -{ - if (m_addresses.size()) - { - for (auto i: m_addresses) - if (_bloom.containsBloom<3>(dev::sha3(i))) - goto OK1; - return false; - } - OK1: - if (m_topics.size()) - { - for (auto i: m_topics) - if (_bloom.containsBloom<3>(dev::sha3(i))) - goto OK2; - return false; - } - OK2: - return true; -} - -bool LogFilter::matches(State const& _s, unsigned _i) const -{ - return matches(_s.receipt(_i)).size() > 0; -} - -LogEntries LogFilter::matches(TransactionReceipt const& _m) const -{ - LogEntries ret; - for (LogEntry const& e: _m.log()) - { - if (!m_addresses.empty() && !m_addresses.count(e.address)) - continue; - for (auto const& t: m_topics) - if (!std::count(e.topics.begin(), e.topics.end(), t)) - continue; - ret.push_back(e); - } - return ret; -} diff --git a/libethereum/MessageFilter.h b/libethereum/MessageFilter.h deleted file mode 100644 index e2c26d214..000000000 --- a/libethereum/MessageFilter.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - This file is part of cpp-ethereum. - - cpp-ethereum 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. - - cpp-ethereum 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 cpp-ethereum. If not, see . -*/ -/** @file MessageFilter.h - * @author Gav Wood - * @date 2014 - */ - -#pragma once - -#include -#include -#include -#include "TransactionReceipt.h" - -namespace dev -{ -namespace eth -{ - -class State; - -class LogFilter -{ -public: - LogFilter(int _earliest = 0, int _latest = -1, unsigned _max = 10, unsigned _skip = 0): m_earliest(_earliest), m_latest(_latest), m_max(_max), m_skip(_skip) {} - - void streamRLP(RLPStream& _s) const; - h256 sha3() const; - - int earliest() const { return m_earliest; } - int latest() const { return m_latest; } - unsigned max() const { return m_max; } - unsigned skip() const { return m_skip; } - bool matches(LogBloom _bloom) const; - bool matches(State const& _s, unsigned _i) const; - LogEntries matches(TransactionReceipt const& _r) const; - - LogFilter address(Address _a) { m_addresses.insert(_a); return *this; } - LogFilter topic(h256 const& _t) { m_topics.insert(_t); return *this; } - LogFilter withMax(unsigned _m) { m_max = _m; return *this; } - LogFilter withSkip(unsigned _m) { m_skip = _m; return *this; } - LogFilter withEarliest(int _e) { m_earliest = _e; return *this; } - LogFilter withLatest(int _e) { m_latest = _e; return *this; } - -private: - AddressSet m_addresses; - h256Set m_topics; - int m_earliest = 0; - int m_latest = -1; - unsigned m_max; - unsigned m_skip; -}; - -} -} diff --git a/libethereum/TransactionReceipt.h b/libethereum/TransactionReceipt.h index b990459d9..feb26dad3 100644 --- a/libethereum/TransactionReceipt.h +++ b/libethereum/TransactionReceipt.h @@ -26,7 +26,6 @@ #include #include #include -#include "Manifest.h" namespace dev { From 94dc92edabb917e2e02dba003678ed95c8ce4663 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 12 Dec 2014 21:56:26 +0100 Subject: [PATCH 170/277] Remove unneeded files. --- libethereum/Client.h | 1 - libethereum/LogFilter.cpp | 81 +++++++++++++++++++++++++++++++++++++ libethereum/LogFilter.h | 69 +++++++++++++++++++++++++++++++ libethereum/PastMessage.cpp | 0 libethereum/PastMessage.h | 0 5 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 libethereum/LogFilter.cpp create mode 100644 libethereum/LogFilter.h delete mode 100644 libethereum/PastMessage.cpp delete mode 100644 libethereum/PastMessage.h diff --git a/libethereum/Client.h b/libethereum/Client.h index 477ea43e5..e8c460093 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -36,7 +36,6 @@ #include "TransactionQueue.h" #include "State.h" #include "CommonNet.h" -#include "PastMessage.h" #include "LogFilter.h" #include "Miner.h" #include "Interface.h" diff --git a/libethereum/LogFilter.cpp b/libethereum/LogFilter.cpp new file mode 100644 index 000000000..81cb439ba --- /dev/null +++ b/libethereum/LogFilter.cpp @@ -0,0 +1,81 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum 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. + + cpp-ethereum 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 cpp-ethereum. If not, see . +*/ +/** @file LogFilter.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "LogFilter.h" + +#include +#include "State.h" +using namespace std; +using namespace dev; +using namespace dev::eth; + +void LogFilter::streamRLP(RLPStream& _s) const +{ + _s.appendList(6) << m_addresses << m_topics << m_earliest << m_latest << m_max << m_skip; +} + +h256 LogFilter::sha3() const +{ + RLPStream s; + streamRLP(s); + return dev::sha3(s.out()); +} + +bool LogFilter::matches(LogBloom _bloom) const +{ + if (m_addresses.size()) + { + for (auto i: m_addresses) + if (_bloom.containsBloom<3>(dev::sha3(i))) + goto OK1; + return false; + } + OK1: + if (m_topics.size()) + { + for (auto i: m_topics) + if (_bloom.containsBloom<3>(dev::sha3(i))) + goto OK2; + return false; + } + OK2: + return true; +} + +bool LogFilter::matches(State const& _s, unsigned _i) const +{ + return matches(_s.receipt(_i)).size() > 0; +} + +LogEntries LogFilter::matches(TransactionReceipt const& _m) const +{ + LogEntries ret; + for (LogEntry const& e: _m.log()) + { + if (!m_addresses.empty() && !m_addresses.count(e.address)) + continue; + for (auto const& t: m_topics) + if (!std::count(e.topics.begin(), e.topics.end(), t)) + continue; + ret.push_back(e); + } + return ret; +} diff --git a/libethereum/LogFilter.h b/libethereum/LogFilter.h new file mode 100644 index 000000000..bda8e46a2 --- /dev/null +++ b/libethereum/LogFilter.h @@ -0,0 +1,69 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum 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. + + cpp-ethereum 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 cpp-ethereum. If not, see . +*/ +/** @file LogFilter.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include "TransactionReceipt.h" + +namespace dev +{ +namespace eth +{ + +class State; + +class LogFilter +{ +public: + LogFilter(int _earliest = 0, int _latest = -1, unsigned _max = 10, unsigned _skip = 0): m_earliest(_earliest), m_latest(_latest), m_max(_max), m_skip(_skip) {} + + void streamRLP(RLPStream& _s) const; + h256 sha3() const; + + int earliest() const { return m_earliest; } + int latest() const { return m_latest; } + unsigned max() const { return m_max; } + unsigned skip() const { return m_skip; } + bool matches(LogBloom _bloom) const; + bool matches(State const& _s, unsigned _i) const; + LogEntries matches(TransactionReceipt const& _r) const; + + LogFilter address(Address _a) { m_addresses.insert(_a); return *this; } + LogFilter topic(h256 const& _t) { m_topics.insert(_t); return *this; } + LogFilter withMax(unsigned _m) { m_max = _m; return *this; } + LogFilter withSkip(unsigned _m) { m_skip = _m; return *this; } + LogFilter withEarliest(int _e) { m_earliest = _e; return *this; } + LogFilter withLatest(int _e) { m_latest = _e; return *this; } + +private: + AddressSet m_addresses; + h256Set m_topics; + int m_earliest = 0; + int m_latest = -1; + unsigned m_max; + unsigned m_skip; +}; + +} +} diff --git a/libethereum/PastMessage.cpp b/libethereum/PastMessage.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/libethereum/PastMessage.h b/libethereum/PastMessage.h deleted file mode 100644 index e69de29bb..000000000 From b364a8110b384d46ea452c33e8141eb15f54cd4e Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 12 Dec 2014 22:00:20 +0100 Subject: [PATCH 171/277] Repotting. --- libethereum/TransactionReceipt.cpp | 51 ++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 libethereum/TransactionReceipt.cpp diff --git a/libethereum/TransactionReceipt.cpp b/libethereum/TransactionReceipt.cpp new file mode 100644 index 000000000..0fb104490 --- /dev/null +++ b/libethereum/TransactionReceipt.cpp @@ -0,0 +1,51 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum 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. + + cpp-ethereum 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 cpp-ethereum. If not, see . +*/ +/** @file TransactionReceipt.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "TransactionReceipt.h" + +using namespace std; +using namespace dev; +using namespace dev::eth; + +TransactionReceipt::TransactionReceipt(bytesConstRef _rlp) +{ + RLP r(_rlp); + m_stateRoot = (h256)r[0]; + m_gasUsed = (u256)r[1]; + m_bloom = (LogBloom)r[2]; + for (auto const& i: r[3]) + m_log.emplace_back(i); +} + +TransactionReceipt::TransactionReceipt(h256 _root, u256 _gasUsed, LogEntries const& _log): + m_stateRoot(_root), + m_gasUsed(_gasUsed), + m_bloom(eth::bloom(_log)), + m_log(_log) +{} + +void TransactionReceipt::streamRLP(RLPStream& _s) const +{ + _s.appendList(4) << m_stateRoot << m_gasUsed << m_bloom; + _s.appendList(m_log.size()); + for (LogEntry const& l: m_log) + l.streamRLP(_s); +} From b52e9cae5a015e822a3f315cb84af96b0f12ec2c Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 12 Dec 2014 22:00:40 +0100 Subject: [PATCH 172/277] Add file. --- libethereum/TransactionReceipt.h | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/libethereum/TransactionReceipt.h b/libethereum/TransactionReceipt.h index feb26dad3..23995c75a 100644 --- a/libethereum/TransactionReceipt.h +++ b/libethereum/TransactionReceipt.h @@ -36,21 +36,15 @@ namespace eth class TransactionReceipt { public: - TransactionReceipt(bytesConstRef _rlp) { RLP r(_rlp); m_stateRoot = (h256)r[0]; m_gasUsed = (u256)r[1]; m_bloom = (LogBloom)r[2]; for (auto const& i: r[3]) m_log.emplace_back(i); } - TransactionReceipt(h256 _root, u256 _gasUsed, LogEntries const& _log): m_stateRoot(_root), m_gasUsed(_gasUsed), m_bloom(eth::bloom(_log)), m_log(_log) {} + TransactionReceipt(bytesConstRef _rlp); + TransactionReceipt(h256 _root, u256 _gasUsed, LogEntries const& _log); h256 const& stateRoot() const { return m_stateRoot; } u256 const& gasUsed() const { return m_gasUsed; } LogBloom const& bloom() const { return m_bloom; } LogEntries const& log() const { return m_log; } - void streamRLP(RLPStream& _s) const - { - _s.appendList(4) << m_stateRoot << m_gasUsed << m_bloom; - _s.appendList(m_log.size()); - for (LogEntry const& l: m_log) - l.streamRLP(_s); - } + void streamRLP(RLPStream& _s) const; bytes rlp() const { RLPStream s; streamRLP(s); return s.out(); } From 1b8f9fdc3b44503890ed1bcb5da8bd5cb8dd83a5 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 12 Dec 2014 22:08:48 +0100 Subject: [PATCH 173/277] Deduplication. --- alethzero/MainWin.cpp | 57 +++---------------------------------------- 1 file changed, 3 insertions(+), 54 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 0e36c7737..fa489ffeb 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -1500,58 +1501,6 @@ void Main::on_destination_currentTextChanged() // updateFee(); } -static bytes dataFromText(QString _s) -{ - bytes ret; - while (_s.size()) - { - QRegExp r("(@|\\$)?\"([^\"]*)\"(\\s.*)?"); - QRegExp d("(@|\\$)?([0-9]+)(\\s*(ether)|(finney)|(szabo))?(\\s.*)?"); - QRegExp h("(@|\\$)?(0x)?(([a-fA-F0-9])+)(\\s.*)?"); - if (r.exactMatch(_s)) - { - for (auto i: r.cap(2)) - ret.push_back((byte)i.toLatin1()); - if (r.cap(1) != "$") - for (int i = r.cap(2).size(); i < 32; ++i) - ret.push_back(0); - else - ret.push_back(0); - _s = r.cap(3); - } - else if (d.exactMatch(_s)) - { - u256 v(d.cap(2).toStdString()); - if (d.cap(6) == "szabo") - v *= dev::eth::szabo; - else if (d.cap(5) == "finney") - v *= dev::eth::finney; - else if (d.cap(4) == "ether") - v *= dev::eth::ether; - bytes bs = dev::toCompactBigEndian(v); - if (d.cap(1) != "$") - for (auto i = bs.size(); i < 32; ++i) - ret.push_back(0); - for (auto b: bs) - ret.push_back(b); - _s = d.cap(7); - } - else if (h.exactMatch(_s)) - { - bytes bs = fromHex((((h.cap(3).size() & 1) ? "0" : "") + h.cap(3)).toStdString()); - if (h.cap(1) != "$") - for (auto i = bs.size(); i < 32; ++i) - ret.push_back(0); - for (auto b: bs) - ret.push_back(b); - _s = h.cap(5); - } - else - _s = _s.mid(1); - } - return ret; -} - static shh::Topic topicFromText(QString _s) { shh::BuildTopic ret; @@ -1679,7 +1628,7 @@ void Main::on_data_textChanged() } else { - m_data = dataFromText(ui->data->toPlainText()); + m_data = parseData(ui->data->toPlainText().toStdString()); ui->code->setHtml(QString::fromStdString(dev::memDump(m_data, 8, true))); if (ethereum()->codeAt(fromString(ui->destination->currentText()), 0).size()) { @@ -2207,7 +2156,7 @@ void Main::on_post_clicked() { shh::Message m; m.setTo(stringToPublic(ui->shhTo->currentText())); - m.setPayload(dataFromText(ui->shhData->toPlainText())); + m.setPayload(parseData(ui->shhData->toPlainText().toStdString())); Public f = stringToPublic(ui->shhFrom->currentText()); Secret from; if (m_server->ids().count(f)) From 4b1fb339bf755b539021f8470329b8cc16862657 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Fri, 12 Dec 2014 22:16:51 +0100 Subject: [PATCH 174/277] Added recursive create test + lesser output for safe VM exceptions --- libethereum/Executive.cpp | 2 +- ...cursiveCreateFiller.json => stRecursiveCreateFiller.json} | 0 test/state.cpp | 5 +++++ test/vm.cpp | 2 +- 4 files changed, 7 insertions(+), 2 deletions(-) rename test/{recursiveCreateFiller.json => stRecursiveCreateFiller.json} (100%) diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index deb3da33e..3bf26cf89 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -188,7 +188,7 @@ bool Executive::go(OnOpFunc const& _onOp) } catch (VMException const& _e) { - clog(StateChat) << "Safe VM Exception: " << diagnostic_information(_e); + clog(StateChat) << "Safe VM Exception"; m_endGas = 0;//m_vm->gas(); m_excepted = true; diff --git a/test/recursiveCreateFiller.json b/test/stRecursiveCreateFiller.json similarity index 100% rename from test/recursiveCreateFiller.json rename to test/stRecursiveCreateFiller.json diff --git a/test/state.cpp b/test/state.cpp index 3fe0fe30b..e1d5def6a 100644 --- a/test/state.cpp +++ b/test/state.cpp @@ -130,6 +130,11 @@ BOOST_AUTO_TEST_CASE(stLogTests) dev::test::executeTests("stLogTests", "/StateTests", dev::test::doStateTests); } +BOOST_AUTO_TEST_CASE(stRecursiveCreate) +{ + dev::test::executeTests("stRecursiveCreate", "/StateTests", dev::test::doStateTests); +} + BOOST_AUTO_TEST_CASE(stSpecialTest) { dev::test::executeTests("stSpecialTest", "/StateTests", dev::test::doStateTests); diff --git a/test/vm.cpp b/test/vm.cpp index f05981d9e..49d6ed104 100644 --- a/test/vm.cpp +++ b/test/vm.cpp @@ -311,7 +311,7 @@ void doVMTests(json_spirit::mValue& v, bool _fillin) } catch (VMException const& _e) { - cnote << "VM did throw an exception: " << diagnostic_information(_e); + cnote << "Safe VM Exception"; vmExceptionOccured = true; } catch (Exception const& _e) From 2d70c4df7e539bc40615d2802de8882f90bbdcfb Mon Sep 17 00:00:00 2001 From: winsvega Date: Sat, 13 Dec 2014 18:55:25 +0300 Subject: [PATCH 175/277] Init code test filler --- test/stInitCodeTestFiller.json | 302 +++++++++++++++++++++++++++++++++ 1 file changed, 302 insertions(+) create mode 100644 test/stInitCodeTestFiller.json diff --git a/test/stInitCodeTestFiller.json b/test/stInitCodeTestFiller.json new file mode 100644 index 000000000..76d8f7957 --- /dev/null +++ b/test/stInitCodeTestFiller.json @@ -0,0 +1,302 @@ +{ + "TransactionContractCreation" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "100000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x600a80600c6000396000f200600160008035811a8100", + "gasLimit" : "599", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "", + "value" : "1" + } + }, + + + "NotEnoughCashContractCreation" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "2", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x600a80600c6000396000f200600160008035811a8100", + "gasLimit" : "599", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "", + "value" : "1" + } + }, + + "OutOfGasContractCreation" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x600a80600c6000396000f200600160008035811a8100", + "gasLimit" : "590", + "gasPrice" : "3", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "", + "value" : "1" + } + }, + + "TransactionSuicideInitCode" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x600a80600c6000396000fff2ffff600160008035811a81", + "gasLimit" : "1000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "", + "value" : "1" + } + }, + + "TransactionStopInitCode" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x600a80600c600039600000f20000600160008035811a81", + "gasLimit" : "1000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "", + "value" : "1" + } + }, + + "TransactionCreateSuicideContract" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x600a80600c6000396000f200ff600160008035811a81", + "gasLimit" : "1000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "", + "value" : "1" + } + }, + + "CallTheContractToCreateEmptyContract" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "095e7baea6a6c7c4c2dfeb977efac326af552d87": { + "balance": "0", + "nonce": 0, + "code": "{(CREATE 0 0 32)}", + "storage": {} + }, + + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "100000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x00", + "gasLimit" : "10000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "1" + } + }, + + "CallRecursiveContract" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "095e7baea6a6c7c4c2dfeb977efac326af552d87": { + "balance": "0", + "nonce": 0, + "code": "{[[ 2 ]](ADDRESS)(CODECOPY 0 0 32)(CREATE 0 0 32)}", + "storage": {} + }, + + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "100000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x00", + "gasLimit" : "10000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "1" + } + }, + + "CallTheContractToCreateContractWithInitCode" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "095e7baea6a6c7c4c2dfeb977efac326af552d87": { + "balance": "10000", + "nonce": 0, + "code": "{[[ 2 ]](ADDRESS)(CODECOPY 0 0 32)(CREATE 0 0 32)}", + "storage": {} + }, + + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "100000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x00", + "gasLimit" : "10000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "1" + } + } +} From 761bd331237a1f4eabf0a14ec6a9bd6f1b43b126 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 13 Dec 2014 19:16:35 +0100 Subject: [PATCH 176/277] Avoid noting safe exceptions unless the user *really* wants it. --- libethereum/Executive.cpp | 13 +++++++------ libethereum/State.h | 1 + 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index 3bf26cf89..773bc2d38 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -166,8 +166,9 @@ bool Executive::go(OnOpFunc const& _onOp) { if (m_vm) { +#if ETH_TIMED_EXECUTIONS boost::timer t; -// auto sgas = m_vm->gas(); +#endif try { m_out = m_vm->go(*m_ext, _onOp); @@ -188,11 +189,9 @@ bool Executive::go(OnOpFunc const& _onOp) } catch (VMException const& _e) { - clog(StateChat) << "Safe VM Exception"; - m_endGas = 0;//m_vm->gas(); + clog(StateSafeExceptions) << "Safe VM Exception. " << diagnostic_information(_e); + m_endGas = 0; m_excepted = true; - - // Write state out only in the case of a non-excepted transaction. m_ext->revert(); } catch (Exception const& _e) @@ -205,7 +204,9 @@ bool Executive::go(OnOpFunc const& _onOp) // TODO: AUDIT: check that this can never reasonably happen. Consider what to do if it does. cwarn << "Unexpected std::exception in VM. This is probably unrecoverable. " << _e.what(); } -// cnote << "VM took:" << t.elapsed() << "; gas used: " << (sgas - m_endGas); +#if ETH_TIMED_EXECUTIONS + cnote << "VM took:" << t.elapsed() << "; gas used: " << (sgas - m_endGas); +#endif } return true; } diff --git a/libethereum/State.h b/libethereum/State.h index afa1f1d2c..a85c622df 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -51,6 +51,7 @@ class BlockChain; struct StateChat: public LogChannel { static const char* name() { return "-S-"; } static const int verbosity = 4; }; struct StateTrace: public LogChannel { static const char* name() { return "=S="; } static const int verbosity = 7; }; struct StateDetail: public LogChannel { static const char* name() { return "/S/"; } static const int verbosity = 14; }; +struct StateSafeExceptions: public LogChannel { static const char* name() { return "(S)"; } static const int verbosity = 21; }; struct PrecompiledAddress { From a1a6dcab3495fe7530564e2c8f787d9723d275e1 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 13 Dec 2014 20:15:08 +0100 Subject: [PATCH 177/277] Core repotting. --- libdevcrypto/Common.h | 5 ++ libethcore/BlockInfo.h | 4 +- libethcore/CommonEth.h | 3 + libethereum/CachedAddressState.cpp | 101 +++++++++++++++++++++ libethereum/CachedAddressState.h | 60 +++++++++++++ libethereum/Executive.cpp | 5 +- libethereum/Precompiled.cpp | 88 ++++++++++++++++++ libethereum/Precompiled.h | 44 +++++++++ libethereum/State.cpp | 137 +---------------------------- libethereum/State.h | 11 --- libevm/ExtVMFace.h | 2 - 11 files changed, 307 insertions(+), 153 deletions(-) create mode 100644 libethereum/CachedAddressState.cpp create mode 100644 libethereum/CachedAddressState.h create mode 100644 libethereum/Precompiled.cpp create mode 100644 libethereum/Precompiled.h diff --git a/libdevcrypto/Common.h b/libdevcrypto/Common.h index 96631fcf9..02d52f495 100644 --- a/libdevcrypto/Common.h +++ b/libdevcrypto/Common.h @@ -45,6 +45,11 @@ using Signature = h520; struct SignatureStruct { + SignatureStruct() {} + SignatureStruct(Signature const& _s) { *(h520*)this = _s; } + SignatureStruct(h256 _r, h256 _s, byte _v): r(_r), s(_s), v(_v) {} + operator Signature() const { return *(h520 const*)this; } + /// @returns true if r,s,v values are valid, otherwise false bool isValid(); diff --git a/libethcore/BlockInfo.h b/libethcore/BlockInfo.h index fc52880fa..18dd53ff3 100644 --- a/libethcore/BlockInfo.h +++ b/libethcore/BlockInfo.h @@ -69,7 +69,7 @@ public: h256 stateRoot; h256 transactionsRoot; h256 receiptsRoot; - h512 logBloom; // TODO LogBloom - get include + LogBloom logBloom; u256 difficulty; u256 number; u256 gasLimit; @@ -118,7 +118,7 @@ public: u256 calculateDifficulty(BlockInfo const& _parent) const; u256 calculateGasLimit(BlockInfo const& _parent) const; - /// No-nonce sha3 of the header only. + /// sha3 of the header only. h256 headerHash(IncludeNonce _n) const; void streamRLP(RLPStream& _s, IncludeNonce _n) const; }; diff --git a/libethcore/CommonEth.h b/libethcore/CommonEth.h index 1965a881a..be7db8434 100644 --- a/libethcore/CommonEth.h +++ b/libethcore/CommonEth.h @@ -44,6 +44,9 @@ std::string formatBalance(u256 _b); /// Get information concerning the currency denominations. std::vector> const& units(); +/// The log bloom's size (512 bit). +using LogBloom = h512; + // The various denominations; here for ease of use where needed within code. static const u256 Uether = ((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000; static const u256 Vether = ((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000; diff --git a/libethereum/CachedAddressState.cpp b/libethereum/CachedAddressState.cpp new file mode 100644 index 000000000..5f9be6944 --- /dev/null +++ b/libethereum/CachedAddressState.cpp @@ -0,0 +1,101 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum 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. + + cpp-ethereum 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 cpp-ethereum. If not, see . +*/ +/** @file CachedAddressState.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "CachedAddressState.h" + +#include +#include +#include "Account.h" +using namespace std; +using namespace dev; +using namespace dev::eth; + +bool CachedAddressState::exists() const +{ + return (m_r && (!m_s || m_s->isAlive())) || (m_s && m_s->isAlive()); +} + +u256 CachedAddressState::balance() const +{ + return m_r ? m_s ? m_s->balance() : m_r[1].toInt() : 0; +} + +u256 CachedAddressState::nonce() const +{ + return m_r ? m_s ? m_s->nonce() : m_r[0].toInt() : 0; +} + +bytes CachedAddressState::code() const +{ + if (m_s && m_s->codeCacheValid()) + return m_s->code(); + h256 h = m_r ? m_s ? m_s->codeHash() : m_r[3].toHash() : EmptySHA3; + return h == EmptySHA3 ? bytes() : asBytes(m_o->lookup(h)); +} + +std::map CachedAddressState::storage() const +{ + std::map ret; + if (m_r) + { + TrieDB memdb(const_cast(m_o), m_r[2].toHash()); // promise we won't alter the overlay! :) + for (auto const& j: memdb) + ret[j.first] = RLP(j.second).toInt(); + } + if (m_s) + for (auto const& j: m_s->storageOverlay()) + if ((!ret.count(j.first) && j.second) || (ret.count(j.first) && ret.at(j.first) != j.second)) + ret[j.first] = j.second; + return ret; +} + +AccountDiff CachedAddressState::diff(CachedAddressState const& _c) +{ + AccountDiff ret; + ret.exist = Diff(exists(), _c.exists()); + ret.balance = Diff(balance(), _c.balance()); + ret.nonce = Diff(nonce(), _c.nonce()); + ret.code = Diff(code(), _c.code()); + auto st = storage(); + auto cst = _c.storage(); + auto it = st.begin(); + auto cit = cst.begin(); + while (it != st.end() || cit != cst.end()) + { + if (it != st.end() && cit != cst.end() && it->first == cit->first && (it->second || cit->second) && (it->second != cit->second)) + ret.storage[it->first] = Diff(it->second, cit->second); + else if (it != st.end() && (cit == cst.end() || it->first < cit->first) && it->second) + ret.storage[it->first] = Diff(it->second, 0); + else if (cit != cst.end() && (it == st.end() || it->first > cit->first) && cit->second) + ret.storage[cit->first] = Diff(0, cit->second); + if (it == st.end()) + ++cit; + else if (cit == cst.end()) + ++it; + else if (it->first < cit->first) + ++it; + else if (it->first > cit->first) + ++cit; + else + ++it, ++cit; + } + return ret; +} diff --git a/libethereum/CachedAddressState.h b/libethereum/CachedAddressState.h new file mode 100644 index 000000000..301f54338 --- /dev/null +++ b/libethereum/CachedAddressState.h @@ -0,0 +1,60 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum 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. + + cpp-ethereum 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 cpp-ethereum. If not, see . +*/ +/** @file CachedAddressState.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include "AccountDiff.h" + +namespace dev +{ + +class OverlayDB; + +namespace eth +{ + +class Account; + +class CachedAddressState +{ +public: + CachedAddressState(std::string const& _rlp, Account const* _s, OverlayDB const* _o): m_rS(_rlp), m_r(m_rS), m_s(_s), m_o(_o) {} + + bool exists() const; + u256 balance() const; + u256 nonce() const; + bytes code() const; + std::map storage() const; + AccountDiff diff(CachedAddressState const& _c); + +private: + std::string m_rS; + RLP m_r; + Account const* m_s; + OverlayDB const* m_o; +}; + +} + +} diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index 773bc2d38..438505f1a 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -28,6 +28,7 @@ #include "Interface.h" #include "State.h" #include "ExtVM.h" +#include "Precompiled.h" using namespace std; using namespace dev; using namespace dev::eth; @@ -98,8 +99,8 @@ bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _sen // cnote << "Transferring" << formatBalance(_value) << "to receiver."; m_s.addBalance(_receiveAddress, _value); - auto it = !(_codeAddress & ~h160(0xffffffff)) ? State::precompiled().find((unsigned)(u160)_codeAddress) : State::precompiled().end(); - if (it != State::precompiled().end()) + auto it = !(_codeAddress & ~h160(0xffffffff)) ? precompiled().find((unsigned)(u160)_codeAddress) : precompiled().end(); + if (it != precompiled().end()) { bigint g = it->second.gas(_data); if (_gas < g) diff --git a/libethereum/Precompiled.cpp b/libethereum/Precompiled.cpp new file mode 100644 index 000000000..1861385da --- /dev/null +++ b/libethereum/Precompiled.cpp @@ -0,0 +1,88 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum 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. + + cpp-ethereum 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 cpp-ethereum. If not, see . +*/ +/** @file Precompiled.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Precompiled.h" + +#include +#include +#include +using namespace std; +using namespace dev; +using namespace dev::eth; + +static bytes ecrecoverCode(bytesConstRef _in) +{ + struct inType + { + h256 hash; + h256 v; + h256 r; + h256 s; + } in; + + memcpy(&in, _in.data(), min(_in.size(), sizeof(in))); + + h256 ret; + + if ((u256)in.v > 28) + return ret.asBytes(); + SignatureStruct sig(in.r, in.s, (byte)((int)(u256)in.v - 27)); + if (!sig.isValid()) + return ret.asBytes(); + + try + { + ret = dev::sha3(recover(sig, in.hash)); + } + catch (...) {} + + memset(ret.data(), 0, 12); + return ret.asBytes(); +} + +static bytes sha256Code(bytesConstRef _in) +{ + bytes ret(32); + sha256(_in, &ret); + return ret; +} + +static bytes ripemd160Code(bytesConstRef _in) +{ + bytes ret(32); + ripemd160(_in, &ret); + // leaves the 20-byte hash left-aligned. we want it right-aligned: + memmove(ret.data() + 12, ret.data(), 20); + memset(ret.data(), 0, 12); + return ret; +} + +static const std::map c_precompiled = +{ + { 1, { [](bytesConstRef) -> bigint { return (bigint)500; }, ecrecoverCode }}, + { 2, { [](bytesConstRef i) -> bigint { return (bigint)50 + (i.size() + 31) / 32 * 50; }, sha256Code }}, + { 3, { [](bytesConstRef i) -> bigint { return (bigint)50 + (i.size() + 31) / 32 * 50; }, ripemd160Code }} +}; + +std::map const& dev::eth::precompiled() +{ + return c_precompiled; +} diff --git a/libethereum/Precompiled.h b/libethereum/Precompiled.h new file mode 100644 index 000000000..c65cd9a63 --- /dev/null +++ b/libethereum/Precompiled.h @@ -0,0 +1,44 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum 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. + + cpp-ethereum 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 cpp-ethereum. If not, see . +*/ +/** @file Precompiled.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include + +namespace dev +{ +namespace eth +{ + +/// Information structure regarding an account that is precompiled (i.e. 1, 2, 3). +struct PrecompiledAddress +{ + std::function gas; + std::function exec; +}; + +/// Info on precompiled contract accounts baked into the protocol. +std::map const& precompiled(); + +} +} diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 30290c315..64210f20a 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -34,6 +34,7 @@ #include "Defaults.h" #include "ExtVM.h" #include "Executive.h" +#include "CachedAddressState.h" using namespace std; using namespace dev; using namespace dev::eth; @@ -42,59 +43,6 @@ using namespace dev::eth; static const u256 c_blockReward = 1500 * finney; -bytes ecrecoverCode(bytesConstRef _in) -{ - struct inType - { - h256 hash; - h256 v; - h256 r; - h256 s; - } in; - - memcpy(&in, _in.data(), min(_in.size(), sizeof(in))); - - h256 ret; - - if ((u256)in.v > 28) - return ret.asBytes(); - SignatureStruct sig{in.r, in.s, (byte)((int)(u256)in.v - 27)}; - if (!sig.isValid()) - return ret.asBytes(); - - byte pubkey[65]; - int pubkeylen = 65; - secp256k1_start(); - if (secp256k1_ecdsa_recover_compact(in.hash.data(), 32, in.r.data(), pubkey, &pubkeylen, 0, (int)(u256)in.v - 27)) - ret = dev::sha3(bytesConstRef(&(pubkey[1]), 64)); - memset(ret.data(), 0, 12); - return ret.asBytes(); -} - -bytes sha256Code(bytesConstRef _in) -{ - bytes ret(32); - sha256(_in, &ret); - return ret; -} - -bytes ripemd160Code(bytesConstRef _in) -{ - bytes ret(32); - ripemd160(_in, &ret); - // leaves the 20-byte hash left-aligned. we want it right-aligned: - memmove(ret.data() + 12, ret.data(), 20); - memset(ret.data(), 0, 12); - return ret; -} - -const std::map State::c_precompiled = -{ - { 1, { [](bytesConstRef) -> bigint { return (bigint)500; }, ecrecoverCode }}, - { 2, { [](bytesConstRef i) -> bigint { return (bigint)50 + (i.size() + 31) / 32 * 50; }, sha256Code }}, - { 3, { [](bytesConstRef i) -> bigint { return (bigint)50 + (i.size() + 31) / 32 * 50; }, ripemd160Code }} -}; - OverlayDB State::openDB(std::string _path, bool _killExisting) { if (_path.empty()) @@ -226,89 +174,6 @@ Address State::nextActiveAddress(Address _a) const return (*it).first; } -// TODO: repot -struct CachedAddressState -{ - CachedAddressState(std::string const& _rlp, Account const* _s, OverlayDB const* _o): rS(_rlp), r(rS), s(_s), o(_o) {} - - bool exists() const - { - return (r && (!s || s->isAlive())) || (s && s->isAlive()); - } - - u256 balance() const - { - return r ? s ? s->balance() : r[1].toInt() : 0; - } - - u256 nonce() const - { - return r ? s ? s->nonce() : r[0].toInt() : 0; - } - - bytes code() const - { - if (s && s->codeCacheValid()) - return s->code(); - h256 h = r ? s ? s->codeHash() : r[3].toHash() : EmptySHA3; - return h == EmptySHA3 ? bytes() : asBytes(o->lookup(h)); - } - - std::map storage() const - { - std::map ret; - if (r) - { - TrieDB memdb(const_cast(o), r[2].toHash()); // promise we won't alter the overlay! :) - for (auto const& j: memdb) - ret[j.first] = RLP(j.second).toInt(); - } - if (s) - for (auto const& j: s->storageOverlay()) - if ((!ret.count(j.first) && j.second) || (ret.count(j.first) && ret.at(j.first) != j.second)) - ret[j.first] = j.second; - return ret; - } - - AccountDiff diff(CachedAddressState const& _c) - { - AccountDiff ret; - ret.exist = Diff(exists(), _c.exists()); - ret.balance = Diff(balance(), _c.balance()); - ret.nonce = Diff(nonce(), _c.nonce()); - ret.code = Diff(code(), _c.code()); - auto st = storage(); - auto cst = _c.storage(); - auto it = st.begin(); - auto cit = cst.begin(); - while (it != st.end() || cit != cst.end()) - { - if (it != st.end() && cit != cst.end() && it->first == cit->first && (it->second || cit->second) && (it->second != cit->second)) - ret.storage[it->first] = Diff(it->second, cit->second); - else if (it != st.end() && (cit == cst.end() || it->first < cit->first) && it->second) - ret.storage[it->first] = Diff(it->second, 0); - else if (cit != cst.end() && (it == st.end() || it->first > cit->first) && cit->second) - ret.storage[cit->first] = Diff(0, cit->second); - if (it == st.end()) - ++cit; - else if (cit == cst.end()) - ++it; - else if (it->first < cit->first) - ++it; - else if (it->first > cit->first) - ++cit; - else - ++it, ++cit; - } - return ret; - } - - std::string rS; - RLP r; - Account const* s; - OverlayDB const* o; -}; - StateDiff State::diff(State const& _c) const { StateDiff ret; diff --git a/libethereum/State.h b/libethereum/State.h index a85c622df..611647566 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -53,12 +53,6 @@ struct StateTrace: public LogChannel { static const char* name() { return "=S="; struct StateDetail: public LogChannel { static const char* name() { return "/S/"; } static const int verbosity = 14; }; struct StateSafeExceptions: public LogChannel { static const char* name() { return "(S)"; } static const int verbosity = 21; }; -struct PrecompiledAddress -{ - std::function gas; - std::function exec; -}; - /** * @brief Model of the current state of the ledger. * Maintains current ledger (m_current) as a fast hash-map. This is hashed only when required (i.e. to create or verify a block). @@ -250,9 +244,6 @@ public: /// the block since all state changes are ultimately reversed. void cleanup(bool _fullCommit); - /// Info on precompiled contract accounts baked into the protocol. - static std::map const& precompiled() { return c_precompiled; } - private: /// Undo the changes to the state for committing to mine. void uncommitToMine(); @@ -311,8 +302,6 @@ private: static std::string c_defaultPath; - static const std::map c_precompiled; - friend std::ostream& operator<<(std::ostream& _out, State const& _s); }; diff --git a/libevm/ExtVMFace.h b/libevm/ExtVMFace.h index b8c4184ab..84dee4272 100644 --- a/libevm/ExtVMFace.h +++ b/libevm/ExtVMFace.h @@ -36,8 +36,6 @@ namespace dev namespace eth { -using LogBloom = h512; - struct LogEntry { LogEntry() {} From efa6fd99b28649e6fd92ae15cc04f38fdc8b95b8 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 13 Dec 2014 21:21:36 +0100 Subject: [PATCH 178/277] Windows fix? --- test/solidityEndToEndTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/solidityEndToEndTest.cpp b/test/solidityEndToEndTest.cpp index 130e44a9a..0970c4f4b 100644 --- a/test/solidityEndToEndTest.cpp +++ b/test/solidityEndToEndTest.cpp @@ -402,7 +402,7 @@ BOOST_AUTO_TEST_CASE(empty_string_on_stack) " }\n" "}\n"; compileAndRun(sourceCode); - BOOST_CHECK(callContractFunction(0, bytes({0x02})) == bytes({0x00, 0x02, 'a', 'b', 'c', 0x00})); + BOOST_CHECK(callContractFunction(0, bytes({0x02})) == bytes({0x00, 0x02, (byte)'a', (byte)'b', (byte)'c', 0x00})); } BOOST_AUTO_TEST_CASE(state_smoke_test) From 24a2c6f2ed6c90281e80c987413ce785b83bd501 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 13 Dec 2014 21:24:13 +0100 Subject: [PATCH 179/277] Another Windows fix? --- test/TestHelper.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index e8940cc7a..0c1ee290f 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -330,9 +330,11 @@ void checkStorage(map _expectedStore, map _resultStore, } } BOOST_CHECK_EQUAL(_resultStore.size(), _expectedStore.size()); +#ifndef __WIN32__ for (auto&& resultStorePair : _resultStore) if (!_expectedStore.count(resultStorePair.first)) BOOST_ERROR(_expectedAddr << ": unexpected store key " << resultStorePair.first); +#endif } void checkLog(LogEntries _resultLogs, LogEntries _expectedLogs) From 35f2985eb9bbc9eb7c000bf42cc1bff0f1a4d7f2 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Sat, 13 Dec 2014 21:39:21 +0100 Subject: [PATCH 180/277] merge --- test/state.cpp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/test/state.cpp b/test/state.cpp index b5b238299..f183c4813 100644 --- a/test/state.cpp +++ b/test/state.cpp @@ -45,7 +45,7 @@ void doStateTests(json_spirit::mValue& v, bool _fillin) { for (auto& i: v.get_obj()) { - cnote << i.first; + cerr << i.first << endl; mObject& o = i.second.get_obj(); BOOST_REQUIRE(o.count("env") > 0); @@ -81,6 +81,9 @@ void doStateTests(json_spirit::mValue& v, bool _fillin) // check output checkOutput(output, o); + // check logs + checkLog(theState.pending().size() ? theState.log(0) : LogEntries(), importer.m_environment.sub.logs); + // check addresses auto expectedAddrs = importer.m_statePost.addresses(); auto resultAddrs = theState.addresses(); @@ -122,6 +125,26 @@ BOOST_AUTO_TEST_CASE(stPreCompiledContracts) dev::test::executeTests("stPreCompiledContracts", "/StateTests", dev::test::doStateTests); } +BOOST_AUTO_TEST_CASE(stLogTests) +{ + dev::test::executeTests("stLogTests", "/StateTests", dev::test::doStateTests); +} + +BOOST_AUTO_TEST_CASE(stRecursiveCreate) +{ + dev::test::executeTests("stRecursiveCreate", "/StateTests", dev::test::doStateTests); +} + +BOOST_AUTO_TEST_CASE(stInitCodeTest) +{ + dev::test::executeTests("stInitCodeTest", "/StateTests", dev::test::doStateTests); +} + +BOOST_AUTO_TEST_CASE(stSpecialTest) +{ + dev::test::executeTests("stSpecialTest", "/StateTests", dev::test::doStateTests); +} + BOOST_AUTO_TEST_CASE(stCreateTest) { for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) From 37c93e0458c9be22cacf9ea382834392ca0e5690 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 13 Dec 2014 21:40:04 +0100 Subject: [PATCH 181/277] Fixes for windows? --- test/TestHelper.cpp | 4 ++-- test/solidityEndToEndTest.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index 0c1ee290f..b700b65a7 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -330,11 +330,11 @@ void checkStorage(map _expectedStore, map _resultStore, } } BOOST_CHECK_EQUAL(_resultStore.size(), _expectedStore.size()); -#ifndef __WIN32__ for (auto&& resultStorePair : _resultStore) + { if (!_expectedStore.count(resultStorePair.first)) BOOST_ERROR(_expectedAddr << ": unexpected store key " << resultStorePair.first); -#endif + } } void checkLog(LogEntries _resultLogs, LogEntries _expectedLogs) diff --git a/test/solidityEndToEndTest.cpp b/test/solidityEndToEndTest.cpp index 0970c4f4b..2c1885ad8 100644 --- a/test/solidityEndToEndTest.cpp +++ b/test/solidityEndToEndTest.cpp @@ -402,7 +402,7 @@ BOOST_AUTO_TEST_CASE(empty_string_on_stack) " }\n" "}\n"; compileAndRun(sourceCode); - BOOST_CHECK(callContractFunction(0, bytes({0x02})) == bytes({0x00, 0x02, (byte)'a', (byte)'b', (byte)'c', 0x00})); + BOOST_CHECK(callContractFunction(0, bytes({0x02})) == bytes({0x00, 0x02, 0x61/*'a'*/, 0x62/*'b'*/, 0x63/*'c'*/, 0x00})); } BOOST_AUTO_TEST_CASE(state_smoke_test) From a068543f21db9efd7e659aa4848d7e959bc711ba Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 13 Dec 2014 21:43:38 +0100 Subject: [PATCH 182/277] State reworked slightly. Additional experimentation for State to demo how easily it is to create states. --- exp/main.cpp | 80 ++++++++------------------------------------- libethereum/State.h | 16 ++++----- 2 files changed, 21 insertions(+), 75 deletions(-) diff --git a/exp/main.cpp b/exp/main.cpp index 8be79cad5..6192ab96c 100644 --- a/exp/main.cpp +++ b/exp/main.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include using namespace std; @@ -36,7 +37,7 @@ using namespace dev::eth; using namespace dev::p2p; using namespace dev::shh; -#if 1 +#if 0 int main() { DownloadMan man; @@ -72,72 +73,17 @@ int main() cnote << i;*/ return 0; } -#endif - -/*int other(bool& o_started) +#else +int main() { - setThreadName("other"); - - short listenPort = 30300; - - Host ph("Test", NetworkPreferences(listenPort, "", false, true)); - auto wh = ph.registerCapability(new WhisperHost()); - - ph.start(); - - o_started = true; - - /// Only interested in odd packets - auto w = wh->installWatch(BuildTopicMask()("odd")); - - unsigned last = 0; - unsigned total = 0; - - for (int i = 0; i < 100 && last < 81; ++i) - { - for (auto i: wh->checkWatch(w)) - { - Message msg = wh->envelope(i).open(); - last = RLP(msg.payload()).toInt(); - cnote << "New message from:" << msg.from().abridged() << RLP(msg.payload()).toInt(); - total += last; - } - this_thread::sleep_for(chrono::milliseconds(50)); - } - return total; + KeyPair u = KeyPair::create(); + KeyPair cb = KeyPair::create(); + OverlayDB db; + State s(cb.address(), db); + cnote << s.rootHash(); + s.addBalance(u.address(), 1000 * ether); + s.commit(); + cnote << s.rootHash(); } +#endif -int main(int, char**) -{ - g_logVerbosity = 0; - - bool started = false; - unsigned result; - std::thread listener([&](){ return (result = other(started)); }); - while (!started) - this_thread::sleep_for(chrono::milliseconds(50)); - - short listenPort = 30303; - string remoteHost = "127.0.0.1"; - short remotePort = 30300; - - Host ph("Test", NetworkPreferences(listenPort, "", false, true)); - auto wh = ph.registerCapability(new WhisperHost()); - - ph.start(); - - if (!remoteHost.empty()) - ph.connect(remoteHost, remotePort); - - KeyPair us = KeyPair::create(); - for (int i = 0; i < 10; ++i) - { - wh->post(us.sec(), RLPStream().append(i * i).out(), BuildTopic(i)(i % 2 ? "odd" : "even")); - this_thread::sleep_for(chrono::milliseconds(250)); - } - - listener.join(); - assert(result == 1 + 9 + 25 + 49 + 81); - - return 0; -}*/ diff --git a/libethereum/State.h b/libethereum/State.h index 611647566..b071e7674 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -244,6 +244,12 @@ public: /// the block since all state changes are ultimately reversed. void cleanup(bool _fullCommit); + /// Commit all changes waiting in the address cache to the DB. + void commit(); + + /// Sets m_currentBlock to a clean state, (i.e. no change from m_previousBlock). + void resetCurrent(); + private: /// Undo the changes to the state for committing to mine. void uncommitToMine(); @@ -257,25 +263,19 @@ private: /// Retrieve all information about a given address into a cache. void ensureCached(std::map& _cache, Address _a, bool _requireCode, bool _forceCreate) const; - /// Commit all changes waiting in the address cache to the DB. - void commit(); - /// Execute the given block, assuming it corresponds to m_currentBlock. If _bc is passed, it will be used to check the uncles. /// Throws on failure. u256 enact(bytesConstRef _block, BlockChain const* _bc = nullptr, bool _checkNonce = true); - /// Sets m_currentBlock to a clean state, (i.e. no change from m_previousBlock). - void resetCurrent(); - /// Finalise the block, applying the earned rewards. void applyRewards(Addresses const& _uncleAddresses); - void refreshManifest(RLPStream* _txs = nullptr); - /// @returns gas used by transactions thus far executed. u256 gasUsed() const { return m_receipts.size() ? m_receipts.back().gasUsed() : 0; } + /// Debugging only. Good for checking the Trie is in shape. bool isTrieGood(bool _enforceRefs, bool _requireNoLeftOvers) const; + /// Debugging only. Good for checking the Trie is in shape. void paranoia(std::string const& _when, bool _enforceRefs = false) const; OverlayDB m_db; ///< Our overlay for the state tree. From 4a0ac1f4c2f294052e052e1a1533302f2509a189 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 13 Dec 2014 21:48:23 +0100 Subject: [PATCH 183/277] Silly windows fix. --- test/solidityEndToEndTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/solidityEndToEndTest.cpp b/test/solidityEndToEndTest.cpp index 2c1885ad8..15722abe1 100644 --- a/test/solidityEndToEndTest.cpp +++ b/test/solidityEndToEndTest.cpp @@ -402,7 +402,7 @@ BOOST_AUTO_TEST_CASE(empty_string_on_stack) " }\n" "}\n"; compileAndRun(sourceCode); - BOOST_CHECK(callContractFunction(0, bytes({0x02})) == bytes({0x00, 0x02, 0x61/*'a'*/, 0x62/*'b'*/, 0x63/*'c'*/, 0x00})); + BOOST_CHECK(callContractFunction(0, bytes(1, 0x02)) == bytes({0x00, 0x02, 0x61/*'a'*/, 0x62/*'b'*/, 0x63/*'c'*/, 0x00})); } BOOST_AUTO_TEST_CASE(state_smoke_test) From 0cd39343eb086ac277fba92c0815894aa0aedb31 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 13 Dec 2014 22:40:57 +0100 Subject: [PATCH 184/277] Demonstration of how to create a completely custom state for execution of transactions. --- exp/main.cpp | 13 +++++++++++-- libethcore/BlockInfo.cpp | 19 +++++++++++++++++++ libethcore/BlockInfo.h | 2 ++ libethereum/ExtVM.h | 1 + libethereum/State.cpp | 39 +++++++++++++++++++++++++++++++++------ libethereum/State.h | 7 ++++++- 6 files changed, 72 insertions(+), 9 deletions(-) diff --git a/exp/main.cpp b/exp/main.cpp index 6192ab96c..aee6e6efd 100644 --- a/exp/main.cpp +++ b/exp/main.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include using namespace std; @@ -79,11 +80,19 @@ int main() KeyPair u = KeyPair::create(); KeyPair cb = KeyPair::create(); OverlayDB db; - State s(cb.address(), db); + State s(cb.address(), db, BaseState::Empty); cnote << s.rootHash(); - s.addBalance(u.address(), 1000 * ether); + s.addBalance(u.address(), 1 * ether); + Address c = s.newContract(1000 * ether, compileLLL("(suicide (caller))")); s.commit(); cnote << s.rootHash(); + State before = s; + cnote << s; + Transaction t(0, 10000, 10000, c, bytes(), 0, u.secret()); + cnote << s.balance(c); + s.execute(t.rlp()); + cnote << before.diff(s); + cnote << s; } #endif diff --git a/libethcore/BlockInfo.cpp b/libethcore/BlockInfo.cpp index bf973b565..6c08bb346 100644 --- a/libethcore/BlockInfo.cpp +++ b/libethcore/BlockInfo.cpp @@ -40,6 +40,25 @@ BlockInfo::BlockInfo(bytesConstRef _block, bool _checkNonce) populate(_block, _checkNonce); } +void BlockInfo::setEmpty() +{ + parentHash = h256(); + sha3Uncles = EmptyListSHA3; + coinbaseAddress = Address(); + stateRoot = EmptyTrie; + transactionsRoot = EmptyTrie; + receiptsRoot = EmptyTrie; + logBloom = LogBloom(); + difficulty = 0; + number = 0; + gasLimit = 0; + gasUsed = 0; + timestamp = 0; + extraData.clear(); + nonce = h256(); + hash = headerHash(WithNonce); +} + BlockInfo BlockInfo::fromHeader(bytesConstRef _block) { BlockInfo ret; diff --git a/libethcore/BlockInfo.h b/libethcore/BlockInfo.h index 18dd53ff3..99efc6a17 100644 --- a/libethcore/BlockInfo.h +++ b/libethcore/BlockInfo.h @@ -108,6 +108,8 @@ public: } bool operator!=(BlockInfo const& _cmp) const { return !operator==(_cmp); } + void setEmpty(); + void populateFromHeader(RLP const& _header, bool _checkNonce = true); void populate(bytesConstRef _block, bool _checkNonce = true); void populate(bytes const& _block, bool _checkNonce = true) { populate(&_block, _checkNonce); } diff --git a/libethereum/ExtVM.h b/libethereum/ExtVM.h index 9699a68ad..cfe40874f 100644 --- a/libethereum/ExtVM.h +++ b/libethereum/ExtVM.h @@ -73,6 +73,7 @@ public: virtual void suicide(Address _a) override final { m_s.addBalance(_a, m_s.balance(myAddress)); + m_s.subBalance(myAddress, m_s.balance(myAddress)); ExtVMFace::suicide(_a); } diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 64210f20a..fd00761e1 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -63,7 +63,7 @@ OverlayDB State::openDB(std::string _path, bool _killExisting) return OverlayDB(db); } -State::State(Address _coinbaseAddress, OverlayDB const& _db): +State::State(Address _coinbaseAddress, OverlayDB const& _db, BaseState _bs): m_db(_db), m_state(&m_db), m_ourAddress(_coinbaseAddress), @@ -74,12 +74,19 @@ State::State(Address _coinbaseAddress, OverlayDB const& _db): paranoia("beginning of normal construction.", true); - dev::eth::commit(genesisState(), m_db, m_state); - m_db.commit(); + if (_bs == BaseState::Genesis) + { + dev::eth::commit(genesisState(), m_db, m_state); + m_db.commit(); - paranoia("after DB commit of normal construction.", true); + paranoia("after DB commit of normal construction.", true); + m_previousBlock = BlockChain::genesis(); + } + else + { + m_previousBlock.setEmpty(); + } - m_previousBlock = BlockChain::genesis(); resetCurrent(); assert(m_state.root() == m_previousBlock.stateRoot); @@ -857,6 +864,23 @@ void State::subBalance(Address _id, bigint _amount) it->second.addBalance(-_amount); } +Address State::newContract(u256 _balance, bytes const& _code) +{ + auto h = sha3(_code); + m_db.insert(h, &_code); + while (true) + { + Address ret = Address::random(); + ensureCached(ret, false, false); + auto it = m_cache.find(ret); + if (it == m_cache.end()) + { + m_cache[ret] = Account(0, _balance, EmptyTrie, h); + return ret; + } + } +} + u256 State::transactionsFrom(Address _id) const { ensureCached(_id, false, false); @@ -993,8 +1017,11 @@ u256 State::execute(bytesConstRef _rlp, bytes* o_output, bool _commit) ctrace << "Executing" << e.t() << "on" << h; ctrace << toHex(e.t().rlp()); #endif - +#if ETH_TRACE e.go(e.simpleTrace()); +#else + e.go(); +#endif e.finalize(); #if ETH_PARANOIA diff --git a/libethereum/State.h b/libethereum/State.h index b071e7674..763a67451 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -53,6 +53,8 @@ struct StateTrace: public LogChannel { static const char* name() { return "=S="; struct StateDetail: public LogChannel { static const char* name() { return "/S/"; } static const int verbosity = 14; }; struct StateSafeExceptions: public LogChannel { static const char* name() { return "(S)"; } static const int verbosity = 21; }; +enum class BaseState { Empty, Genesis }; + /** * @brief Model of the current state of the ledger. * Maintains current ledger (m_current) as a fast hash-map. This is hashed only when required (i.e. to create or verify a block). @@ -66,7 +68,7 @@ class State public: /// Construct state object. - State(Address _coinbaseAddress = Address(), OverlayDB const& _db = OverlayDB()); + State(Address _coinbaseAddress = Address(), OverlayDB const& _db = OverlayDB(), BaseState _bs = BaseState::Genesis); /// Construct state object from arbitrary point in blockchain. State(OverlayDB const& _db, BlockChain const& _bc, h256 _hash); @@ -183,6 +185,9 @@ public: /// Set the value of a storage position of an account. void setStorage(Address _contract, u256 _location, u256 _value) { m_cache[_contract].setStorage(_location, _value); } + /// Create a new contract. + Address newContract(u256 _balance, bytes const& _code); + /// Get the storage of an account. /// @note This is expensive. Don't use it unless you need to. /// @returns std::map if no account exists at that address. From bf3fbae3979d2d8d3efacb7f50abf4eac7ab7412 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 13 Dec 2014 22:44:28 +0100 Subject: [PATCH 185/277] Demonstration readability improved. Clear how the State diff works. --- exp/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/exp/main.cpp b/exp/main.cpp index aee6e6efd..3c4a1b207 100644 --- a/exp/main.cpp +++ b/exp/main.cpp @@ -85,14 +85,14 @@ int main() s.addBalance(u.address(), 1 * ether); Address c = s.newContract(1000 * ether, compileLLL("(suicide (caller))")); s.commit(); - cnote << s.rootHash(); State before = s; - cnote << s; + cnote << "State before transaction: " << before; Transaction t(0, 10000, 10000, c, bytes(), 0, u.secret()); + cnote << "Transaction: " << t; cnote << s.balance(c); s.execute(t.rlp()); + cnote << "State after transaction: " << s; cnote << before.diff(s); - cnote << s; } #endif From 1e80a16ec84e83d9176506a2a9ca4091dc6d0f03 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Sat, 13 Dec 2014 23:46:20 +0100 Subject: [PATCH 186/277] fixed macdeplyqt path on macos --- cmake/EthDependencies.cmake | 11 +++++++++++ cmake/EthExecutableHelper.cmake | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 24e5bd07d..ee93a5311 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -17,6 +17,11 @@ if (WIN32) #set (CMAKE_PREFIX_PATH "C:/Program Files/Windows Kits/8.1/Lib/winv6.3/um/x64") endif() +# homebrew installs qts in opt +if (APPLE) + set (CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "/usr/local/opt/qt5") +endif() + # Dependencies must have a version number, to ensure reproducible build. The version provided here is the one that is in the extdep repository. If you use system libraries, version numbers may be different. find_package (CryptoPP 5.6.2 EXACT REQUIRED) @@ -102,6 +107,12 @@ if (NOT HEADLESS) find_package (Qt5WebKit REQUIRED) find_package (Qt5WebKitWidgets REQUIRED) + # we need to find path to macdeployqt on mac + if (APPLE) + set (MACDEPLOYQT_APP ${Qt5Core_DIR}/../../../bin/macdeployqt) + message(" - macdeployqt path: ${MACDEPLOYQT_APP}") + endif() + endif() #HEADLESS # use multithreaded boost libraries, with -mt suffix diff --git a/cmake/EthExecutableHelper.cmake b/cmake/EthExecutableHelper.cmake index adda57692..56aa3f6c3 100644 --- a/cmake/EthExecutableHelper.cmake +++ b/cmake/EthExecutableHelper.cmake @@ -66,7 +66,7 @@ macro(eth_install_executable EXECUTABLE) if (APPLE) # First have qt5 install plugins and frameworks add_custom_command(TARGET ${EXECUTABLE} POST_BUILD - COMMAND ${ETH_DEPENDENCY_INSTALL_DIR}/bin/macdeployqt ${eth_qml_dir} ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app + COMMAND ${MACDEPLOYQT_APP} ${eth_qml_dir} ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) # This tool and next will inspect linked libraries in order to determine which dependencies are required From 5162715101adc9df8b3713039a9f33479e2eb9a0 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Sun, 14 Dec 2014 00:10:52 +0100 Subject: [PATCH 187/277] ungly fix for compiling exp on mac --- exp/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/exp/main.cpp b/exp/main.cpp index 3c4a1b207..27707decb 100644 --- a/exp/main.cpp +++ b/exp/main.cpp @@ -20,6 +20,7 @@ * Ethereum client. */ #include +#include #include #include #include From 960f62b05a9a61300400dd566d5ad815f24e3101 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Sun, 14 Dec 2014 21:20:59 +0800 Subject: [PATCH 188/277] update to the correct file name --- alethzero/OurWebThreeStubServer.cpp | 2 +- alethzero/OurWebThreeStubServer.h | 2 +- libdevcore/CommonData.cpp | 2 +- libdevcore/CommonData.h | 2 +- libdevcore/RangeMask.h | 2 +- libdevcrypto/OverlayDB.cpp | 2 +- libdevcrypto/OverlayDB.h | 2 +- libdevcrypto/SHA3.h | 2 +- libethereum/CommonNet.cpp | 2 +- libethereum/CommonNet.h | 2 +- libevmcore/Assembly.h | 2 +- libp2p/HostCapability.h | 2 +- libwhisper/Interface.h | 2 +- mix/CodeEditorExtensionManager.cpp | 2 +- mix/CodeEditorExtensionManager.h | 2 +- mix/ConstantCompilationCtrl.cpp | 2 +- mix/ConstantCompilationCtrl.h | 2 +- mix/ConstantCompilationModel.cpp | 2 +- mix/ConstantCompilationModel.h | 2 +- mix/Extension.cpp | 2 +- mix/Extension.h | 2 +- mix/MixApplication.cpp | 2 +- mix/MixApplication.h | 2 +- test/genesis.cpp | 2 +- test/hexPrefix.cpp | 2 +- 25 files changed, 25 insertions(+), 25 deletions(-) diff --git a/alethzero/OurWebThreeStubServer.cpp b/alethzero/OurWebThreeStubServer.cpp index fec0f9e8d..0c6f42b5a 100644 --- a/alethzero/OurWebThreeStubServer.cpp +++ b/alethzero/OurWebThreeStubServer.cpp @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file OurWebThreeStubServer.h +/** @file OurWebThreeStubServer.cpp * @author Gav Wood * @date 2014 */ diff --git a/alethzero/OurWebThreeStubServer.h b/alethzero/OurWebThreeStubServer.h index ef13964b9..fb026d07e 100644 --- a/alethzero/OurWebThreeStubServer.h +++ b/alethzero/OurWebThreeStubServer.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file OurWebThreeStubServer.cpp +/** @file OurWebThreeStubServer.h * @author Gav Wood * @date 2014 */ diff --git a/libdevcore/CommonData.cpp b/libdevcore/CommonData.cpp index 215f9c4b3..fc3910cfe 100644 --- a/libdevcore/CommonData.cpp +++ b/libdevcore/CommonData.cpp @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file Common.cpp +/** @file CommonData.cpp * @author Gav Wood * @date 2014 */ diff --git a/libdevcore/CommonData.h b/libdevcore/CommonData.h index 5f14f38f8..87d2f5e28 100644 --- a/libdevcore/CommonData.h +++ b/libdevcore/CommonData.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file Common.h +/** @file CommonData.h * @author Gav Wood * @date 2014 * diff --git a/libdevcore/RangeMask.h b/libdevcore/RangeMask.h index ac58ec8b1..19262515c 100644 --- a/libdevcore/RangeMask.h +++ b/libdevcore/RangeMask.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file EthereumHost.h +/** @file RangeMask.h * @author Gav Wood * @date 2014 */ diff --git a/libdevcrypto/OverlayDB.cpp b/libdevcrypto/OverlayDB.cpp index 8ccae6606..9e110bb84 100644 --- a/libdevcrypto/OverlayDB.cpp +++ b/libdevcrypto/OverlayDB.cpp @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file TrieDB.cpp +/** @file OverlayDB.cpp * @author Gav Wood * @date 2014 */ diff --git a/libdevcrypto/OverlayDB.h b/libdevcrypto/OverlayDB.h index 777d1e7df..e9bd53343 100644 --- a/libdevcrypto/OverlayDB.h +++ b/libdevcrypto/OverlayDB.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file MemoryDB.h +/** @file OverlayDB.h * @author Gav Wood * @date 2014 */ diff --git a/libdevcrypto/SHA3.h b/libdevcrypto/SHA3.h index f27e378ba..66b8efe11 100644 --- a/libdevcrypto/SHA3.h +++ b/libdevcrypto/SHA3.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file FixedHash.h +/** @file SHA3.h * @author Gav Wood * @date 2014 * diff --git a/libethereum/CommonNet.cpp b/libethereum/CommonNet.cpp index eb92f0b18..5a9d3d0c9 100644 --- a/libethereum/CommonNet.cpp +++ b/libethereum/CommonNet.cpp @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file PeerNetwork.cpp +/** @file CommonNet.cpp * @author Gav Wood * @date 2014 */ diff --git a/libethereum/CommonNet.h b/libethereum/CommonNet.h index 4192c861e..2ee260650 100644 --- a/libethereum/CommonNet.h +++ b/libethereum/CommonNet.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file PeerNetwork.h +/** @file CommonNet.h * @author Gav Wood * @date 2014 * diff --git a/libevmcore/Assembly.h b/libevmcore/Assembly.h index b144dd8d9..5523710d4 100644 --- a/libevmcore/Assembly.h +++ b/libevmcore/Assembly.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file CodeFragment.h +/** @file Assembly.h * @author Gav Wood * @date 2014 */ diff --git a/libp2p/HostCapability.h b/libp2p/HostCapability.h index da454860a..9666ef65a 100644 --- a/libp2p/HostCapability.h +++ b/libp2p/HostCapability.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file Common.h +/** @file HostCapability.h * @author Gav Wood * @date 2014 * diff --git a/libwhisper/Interface.h b/libwhisper/Interface.h index 1af93f591..0b7b52cf7 100644 --- a/libwhisper/Interface.h +++ b/libwhisper/Interface.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file WhisperHost.h +/** @file Interface.h * @author Gav Wood * @date 2014 */ diff --git a/mix/CodeEditorExtensionManager.cpp b/mix/CodeEditorExtensionManager.cpp index c778d466f..9d0e8508d 100644 --- a/mix/CodeEditorExtensionManager.cpp +++ b/mix/CodeEditorExtensionManager.cpp @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file CodeEditorExtensionMan.cpp +/** @file CodeEditorExtensionManager.cpp * @author Yann yann@ethdev.com * @date 2014 * Ethereum IDE client. diff --git a/mix/CodeEditorExtensionManager.h b/mix/CodeEditorExtensionManager.h index 2b8402bf2..522429511 100644 --- a/mix/CodeEditorExtensionManager.h +++ b/mix/CodeEditorExtensionManager.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file CodeEditorExtensionMan.h +/** @file CodeEditorExtensionManager.h * @author Yann yann@ethdev.com * @date 2014 * Ethereum IDE client. diff --git a/mix/ConstantCompilationCtrl.cpp b/mix/ConstantCompilationCtrl.cpp index 06b9c0284..12eca8a40 100644 --- a/mix/ConstantCompilationCtrl.cpp +++ b/mix/ConstantCompilationCtrl.cpp @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file ConstantCompilation.cpp +/** @file ConstantCompilationCtrl.cpp * @author Yann yann@ethdev.com * @date 2014 * Ethereum IDE client. diff --git a/mix/ConstantCompilationCtrl.h b/mix/ConstantCompilationCtrl.h index e4661c800..8e32b7589 100644 --- a/mix/ConstantCompilationCtrl.h +++ b/mix/ConstantCompilationCtrl.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file ConstantCompilation.h +/** @file ConstantCompilationCtrl.h * @author Yann yann@ethdev.com * @date 2014 * Ethereum IDE client. diff --git a/mix/ConstantCompilationModel.cpp b/mix/ConstantCompilationModel.cpp index ea12a267c..722305763 100644 --- a/mix/ConstantCompilationModel.cpp +++ b/mix/ConstantCompilationModel.cpp @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file ApplicationCtx.h +/** @file ConstantCompilationModel.cpp * @author Yann yann@ethdev.com * @date 2014 * Ethereum IDE client. diff --git a/mix/ConstantCompilationModel.h b/mix/ConstantCompilationModel.h index 4a17853f6..9b8855a3e 100644 --- a/mix/ConstantCompilationModel.h +++ b/mix/ConstantCompilationModel.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file ApplicationCtx.h +/** @file ConstantCompilationModel.h * @author Yann yann@ethdev.com * @date 2014 * Ethereum IDE client. diff --git a/mix/Extension.cpp b/mix/Extension.cpp index 5aeb0cc17..cb1394194 100644 --- a/mix/Extension.cpp +++ b/mix/Extension.cpp @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file Feature.cpp +/** @file Extension.cpp * @author Yann yann@ethdev.com * @date 2014 * Ethereum IDE client. diff --git a/mix/Extension.h b/mix/Extension.h index f8fef0aa6..84fe8e2dc 100644 --- a/mix/Extension.h +++ b/mix/Extension.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file Feature.h +/** @file Extension.h * @author Yann yann@ethdev.com * @date 2014 * Ethereum IDE client. diff --git a/mix/MixApplication.cpp b/mix/MixApplication.cpp index e67ca1b12..d374188b9 100644 --- a/mix/MixApplication.cpp +++ b/mix/MixApplication.cpp @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file main.cpp +/** @file MixApplication.cpp * @author Yann yann@ethdev.com * @date 2014 */ diff --git a/mix/MixApplication.h b/mix/MixApplication.h index fdc506268..b0ea0f216 100644 --- a/mix/MixApplication.h +++ b/mix/MixApplication.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file main.cpp +/** @file MixApplication.h * @author Yann yann@ethdev.com * @date 2014 * This class will be use instead of QApplication to launch the application. the method 'notify' allows to catch all exceptions. diff --git a/test/genesis.cpp b/test/genesis.cpp index 1b354dab8..8cdb84024 100644 --- a/test/genesis.cpp +++ b/test/genesis.cpp @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file trie.cpp +/** @file genesis.cpp * @author Gav Wood * @date 2014 * Trie test functions. diff --git a/test/hexPrefix.cpp b/test/hexPrefix.cpp index 1f02bac91..551983db3 100644 --- a/test/hexPrefix.cpp +++ b/test/hexPrefix.cpp @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file main.cpp +/** @file hexPrefix.cpp * @author Gav Wood * @date 2014 * Main test functions. From 5652bd37790be8b0ce9ccb70f0220a9dfdbf8e6f Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Sun, 14 Dec 2014 21:21:35 +0800 Subject: [PATCH 189/277] typo fix --- libp2p/Session.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libp2p/Session.h b/libp2p/Session.h index e8de1c398..cd2dbf5a7 100644 --- a/libp2p/Session.h +++ b/libp2p/Session.h @@ -110,7 +110,7 @@ private: std::array m_data; ///< Data buffer for the write queue. bytes m_incoming; ///< The incoming read queue of bytes. - PeerInfo m_info; ///< Dyanamic information about this peer. + PeerInfo m_info; ///< Dynamic information about this peer. unsigned m_protocolVersion = 0; ///< The protocol version of the peer. std::shared_ptr m_node; ///< The Node object. Might be null if we constructed using a bare address/port. From 092528d87aba350c01f58b4c24cc4405d2da2f57 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 14 Dec 2014 18:48:43 +0100 Subject: [PATCH 190/277] Minor fix for finalize. --- libethereum/Executive.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index 438505f1a..ed3077628 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -220,7 +220,8 @@ bool Executive::go(OnOpFunc const& _onOp) void Executive::finalize(OnOpFunc const&) { // SSTORE refunds. - m_endGas += min((m_t.gas() - m_endGas) / 2, m_ext->sub.refunds); + if (m_ext) + m_endGas += min((m_t.gas() - m_endGas) / 2, m_ext->sub.refunds); // cnote << "Refunding" << formatBalance(m_endGas * m_ext->gasPrice) << "to origin (=" << m_endGas << "*" << formatBalance(m_ext->gasPrice) << ")"; m_s.addBalance(m_sender, m_endGas * m_t.gasPrice()); From b6aa6efb4623674b2898607827fe4060e1e2a56f Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 14 Dec 2014 18:49:44 +0100 Subject: [PATCH 191/277] Another fix for finalize. --- libethereum/Executive.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index ed3077628..f05591ba2 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -236,5 +236,6 @@ void Executive::finalize(OnOpFunc const&) m_s.m_cache[a].kill(); // Logs - m_logs = m_ext->sub.logs; + if (m_ext) + m_logs = m_ext->sub.logs; } From 302c16ec4475c73c77f4ebd799182e4beaa8cc3a Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 14 Dec 2014 21:10:17 +0100 Subject: [PATCH 192/277] Documentation and reduction. --- libethereum/Executive.cpp | 37 ++++++++++--------- libethereum/Executive.h | 75 +++++++++++++++++++++++++++------------ libethereum/ExtVM.cpp | 4 +-- 3 files changed, 72 insertions(+), 44 deletions(-) diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index f05591ba2..d16cf794c 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -40,15 +40,19 @@ u256 Executive::gasUsed() const return m_t.gas() - m_endGas; } +void Executive::accrueSubState(SubState& _parentContext) +{ + if (m_ext) + _parentContext += m_ext->sub; +} + bool Executive::setup(bytesConstRef _rlp) { // Entry point for a user-executed transaction. m_t = Transaction(_rlp); - m_sender = m_t.sender(); - // Avoid invalid transactions. - auto nonceReq = m_s.transactionsFrom(m_sender); + auto nonceReq = m_s.transactionsFrom(m_t.sender()); if (m_t.nonce() != nonceReq) { clog(StateDetail) << "Invalid Nonce: Require" << nonceReq << " Got" << m_t.nonce(); @@ -67,10 +71,10 @@ bool Executive::setup(bytesConstRef _rlp) u256 cost = m_t.value() + m_t.gas() * m_t.gasPrice(); // Avoid unaffordable transactions. - if (m_s.balance(m_sender) < cost) + if (m_s.balance(m_t.sender()) < cost) { - clog(StateDetail) << "Not enough cash: Require >" << cost << " Got" << m_s.balance(m_sender); - BOOST_THROW_EXCEPTION(NotEnoughCash() << RequirementError((bigint)cost, (bigint)m_s.balance(m_sender))); + clog(StateDetail) << "Not enough cash: Require >" << cost << " Got" << m_s.balance(m_t.sender()); + BOOST_THROW_EXCEPTION(NotEnoughCash() << RequirementError((bigint)cost, (bigint)m_s.balance(m_t.sender()))); } u256 startGasUsed = m_s.gasUsed(); @@ -81,16 +85,16 @@ bool Executive::setup(bytesConstRef _rlp) } // Increment associated nonce for sender. - m_s.noteSending(m_sender); + m_s.noteSending(m_t.sender()); // Pay... clog(StateDetail) << "Paying" << formatBalance(cost) << "from sender (includes" << m_t.gas() << "gas at" << formatBalance(m_t.gasPrice()) << ")"; - m_s.subBalance(m_sender, cost); + m_s.subBalance(m_t.sender(), cost); if (m_t.isCreation()) - return create(m_sender, m_t.value(), m_t.gasPrice(), m_t.gas() - (u256)gasCost, &m_t.data(), m_sender); + return create(m_t.sender(), m_t.value(), m_t.gasPrice(), m_t.gas() - (u256)gasCost, &m_t.data(), m_t.sender()); else - return call(m_t.receiveAddress(), m_t.receiveAddress(), m_sender, m_t.value(), m_t.gasPrice(), bytesConstRef(&m_t.data()), m_t.gas() - (u256)gasCost, m_sender); + return call(m_t.receiveAddress(), m_t.receiveAddress(), m_t.sender(), m_t.value(), m_t.gasPrice(), bytesConstRef(&m_t.data()), m_t.gas() - (u256)gasCost, m_t.sender()); } bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256 _gas, Address _originAddress) @@ -212,22 +216,17 @@ bool Executive::go(OnOpFunc const& _onOp) return true; } -/*u256 Executive::gas() const -{ - return m_vm ? m_vm->gas() : m_endGas; -}*/ - void Executive::finalize(OnOpFunc const&) { - // SSTORE refunds. + // SSTORE refunds... + // must be done before the miner gets the fees. if (m_ext) m_endGas += min((m_t.gas() - m_endGas) / 2, m_ext->sub.refunds); // cnote << "Refunding" << formatBalance(m_endGas * m_ext->gasPrice) << "to origin (=" << m_endGas << "*" << formatBalance(m_ext->gasPrice) << ")"; - m_s.addBalance(m_sender, m_endGas * m_t.gasPrice()); + m_s.addBalance(m_t.sender(), m_endGas * m_t.gasPrice()); u256 feesEarned = (m_t.gas() - m_endGas) * m_t.gasPrice(); -// cnote << "Transferring" << formatBalance(gasSpent) << "to miner."; m_s.addBalance(m_s.m_currentBlock.coinbaseAddress, feesEarned); // Suicides... @@ -235,7 +234,7 @@ void Executive::finalize(OnOpFunc const&) for (auto a: m_ext->sub.suicides) m_s.m_cache[a].kill(); - // Logs + // Logs.. if (m_ext) m_logs = m_ext->sub.logs; } diff --git a/libethereum/Executive.h b/libethereum/Executive.h index c5baada1d..729014bef 100644 --- a/libethereum/Executive.h +++ b/libethereum/Executive.h @@ -39,53 +39,82 @@ struct Manifest; struct VMTraceChannel: public LogChannel { static const char* name() { return "EVM"; } static const int verbosity = 11; }; - +/** + * @brief Message-call/contract-creation executor; useful for executing transactions. + * + * Two ways of using this class - either as a transaction executive or a CALL/CREATE executive. + * In the first use, after construction, begin with setup() and end with finalize(). Call go() + * after setup() only if it returns false. + * In the second use, after construction, begin with call() or create() and end with + * accrueSubState(). Call go() after call()/create() only if it returns false. + */ class Executive { public: + /// Basic constructor. Executive(State& _s, unsigned _level): m_s(_s), m_depth(_level) {} + /// Basic destructor. ~Executive() = default; + Executive(Executive const&) = delete; void operator=(Executive) = delete; + /// Set up the executive for evaluating a transaction. You must call finalize() following this. + /// @returns true iff go() must be called (and thus a VM execution in required). bool setup(bytesConstRef _transaction); + /// Finalise a transaction previously set up with setup(). + /// @warning Only valid after setup(), and possibly go(). + void finalize(OnOpFunc const& _onOp = OnOpFunc()); + /// @returns the transaction from setup(). + /// @warning Only valid after setup(). + Transaction const& t() const { return m_t; } + /// @returns the log entries created by this operation. + /// @warning Only valid after finalise(). + LogEntries const& logs() const { return m_logs; } + /// @returns total gas used in the transaction/operation. + /// @warning Only valid after finalise(). + u256 gasUsed() const; + + /// Set up the executive for evaluating a bare CREATE (contract-creation) operation. + /// @returns false iff go() must be called (and thus a VM execution in required). bool create(Address _txSender, u256 _endowment, u256 _gasPrice, u256 _gas, bytesConstRef _code, Address _originAddress); + /// Set up the executive for evaluating a bare CALL (message call) operation. + /// @returns false iff go() must be called (and thus a VM execution in required). bool call(Address _myAddress, Address _codeAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256 _gas, Address _originAddress); + /// Finalise an operation through accruing the substate into the parent context. + void accrueSubState(SubState& _parentContext); + + /// Executes (or continues execution of) the VM. + /// @returns false iff go() must be called again to finish the transction. bool go(OnOpFunc const& _onOp = OnOpFunc()); - void finalize(OnOpFunc const& _onOp = OnOpFunc()); - u256 gasUsed() const; + /// Operation function for providing a simple trace of the VM execution. static OnOpFunc simpleTrace(); - Transaction const& t() const { return m_t; } - + /// @returns gas remaining after the transaction/operation. u256 endGas() const { return m_endGas; } - + /// @returns output data of the transaction/operation. bytesConstRef out() const { return m_out; } + /// @returns the new address for the created contract in the CREATE operation. h160 newAddress() const { return m_newAddress; } - LogEntries const& logs() const { return m_logs; } + /// @returns true iff the operation ended with a VM exception. bool excepted() const { return m_excepted; } - VMFace const& vm() const { return *m_vm; } - ExtVM const& ext() const { return *m_ext; } - State const& state() const { return m_s; } - private: - State& m_s; - std::shared_ptr m_ext; - std::unique_ptr m_vm; + State& m_s; ///< The state to which this operation/transaction is applied. + std::shared_ptr m_ext; ///< The VM externality object for the VM execution or null if no VM is required. + std::unique_ptr m_vm; ///< The VM object or null if no VM is required. bytes m_precompiledOut; ///< Used for the output when there is no VM for a contract (i.e. precompiled). - bytesConstRef m_out; ///< Holds the copyable output. - Address m_newAddress; + bytesConstRef m_out; ///< The copyable output. + Address m_newAddress; ///< The address of the created contract in the case of create() being called. - Transaction m_t; - bool m_isCreation; - bool m_excepted = false; - unsigned m_depth = 0; - Address m_sender; - u256 m_endGas; + unsigned m_depth = 0; ///< The context's call-depth. + bool m_isCreation = false; ///< True if the transaction creates a contract, or if create() is called. + bool m_excepted = false; ///< True if the VM execution resulted in an exception. + u256 m_endGas; ///< The final amount of gas for the transaction. - LogEntries m_logs; + Transaction m_t; ///< The original transaction in the case that setup() was called. + LogEntries m_logs; ///< The log entries created by this transaction. Only valid }; } diff --git a/libethereum/ExtVM.cpp b/libethereum/ExtVM.cpp index fcd703b25..a005a030b 100644 --- a/libethereum/ExtVM.cpp +++ b/libethereum/ExtVM.cpp @@ -32,7 +32,7 @@ bool ExtVM::call(Address _receiveAddress, u256 _txValue, bytesConstRef _txData, if (!e.call(_receiveAddress, _codeAddressOverride ? _codeAddressOverride : _receiveAddress, _myAddressOverride ? _myAddressOverride : myAddress, _txValue, gasPrice, _txData, io_gas, origin)) { e.go(_onOp); - sub += e.ext().sub; + e.accrueSubState(sub); } io_gas = e.endGas(); e.out().copyTo(_out); @@ -49,7 +49,7 @@ h160 ExtVM::create(u256 _endowment, u256& io_gas, bytesConstRef _code, OnOpFunc if (!e.create(myAddress, _endowment, gasPrice, io_gas, _code, origin)) { e.go(_onOp); - sub += e.ext().sub; + e.accrueSubState(sub); } io_gas = e.endGas(); return e.newAddress(); From 8eee0a2033d3539ffc1bf311a5021322d7bc4fe5 Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 15 Dec 2014 01:02:33 +0100 Subject: [PATCH 193/277] Correctly check for string prefix plus indentation change. --- libsolidity/ExpressionCompiler.cpp | 2 +- libsolidity/Types.cpp | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index add5f73be..f872e0581 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -291,7 +291,7 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) IntegerType(0, IntegerType::Modifier::ADDRESS), true); m_context << eth::Instruction::BALANCE; } - else if (member == "send" || member.substr(0, 4) == "call") + else if (member == "send" || member.substr(0, min(member.size(), 4)) == "call") appendTypeConversion(*_memberAccess.getExpression().getType(), IntegerType(0, IntegerType::Modifier::ADDRESS), true); else diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index a0a809b9b..c2d488418 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -193,14 +193,18 @@ u256 IntegerType::literalValue(Literal const& _literal) const } const MemberList IntegerType::AddressMemberList = - MemberList({{"balance", make_shared(256)}, - {"callstring32", make_shared(TypePointers({make_shared(32)}), - TypePointers(), FunctionType::Location::BARE)}, - {"callstring32string32", make_shared(TypePointers({make_shared(32), - make_shared(32)}), - TypePointers(), FunctionType::Location::BARE)}, - {"send", make_shared(TypePointers({make_shared(256)}), - TypePointers(), FunctionType::Location::SEND)}}); + MemberList({{"balance", + make_shared(256)}, + {"callstring32", + make_shared(TypePointers({make_shared(32)}), + TypePointers(), FunctionType::Location::BARE)}, + {"callstring32string32", + make_shared(TypePointers({make_shared(32), + make_shared(32)}), + TypePointers(), FunctionType::Location::BARE)}, + {"send", + make_shared(TypePointers({make_shared(256)}), + TypePointers(), FunctionType::Location::SEND)}}); shared_ptr StaticStringType::smallestTypeForLiteral(string const& _literal) { From d76b3f472e1751ec3f4d080c16bdaf1fe7e3b1e0 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 15 Dec 2014 09:57:10 +0100 Subject: [PATCH 194/277] - Send String value to QML instead of int value (gas, gasCost, gasLeft). - Wrap label with QApplication::tr (localization). - Use of std::hex, std::dec instead of QTextStream (to avoid warning). --- mix/DebuggingStateWrapper.cpp | 41 +++++++++++++++++++++++++---------- mix/DebuggingStateWrapper.h | 10 +++++---- mix/qml/js/Debugger.js | 5 ++--- 3 files changed, 38 insertions(+), 18 deletions(-) diff --git a/mix/DebuggingStateWrapper.cpp b/mix/DebuggingStateWrapper.cpp index 2315cd5a8..36b098379 100644 --- a/mix/DebuggingStateWrapper.cpp +++ b/mix/DebuggingStateWrapper.cpp @@ -20,9 +20,8 @@ * Used to translate c++ type (u256, bytes, ...) into friendly value (to be used by QML). */ +#include #include -#include -#include #include "libevmcore/Instruction.h" #include "libdevcore/CommonJS.h" #include "libdevcrypto/Common.h" @@ -44,7 +43,7 @@ std::tuple, QQMLMap*> DebuggingStateWrapper::getHumanReadableCod { QString s = QString::fromStdString(instructionInfo((Instruction)b).name); std::ostringstream out; - out << hex << std::setw(4) << std::setfill('0') << i; + out << std::hex << std::setw(4) << std::setfill('0') << i; codeMapping[i] = codeStr.size(); int line = i; if (b >= (byte)Instruction::PUSH1 && b <= (byte)Instruction::PUSH32) @@ -66,6 +65,27 @@ std::tuple, QQMLMap*> DebuggingStateWrapper::getHumanReadableCod return std::make_tuple(codeStr, new QQMLMap(codeMapping, _objUsedAsParent)); } +QString DebuggingStateWrapper::gasLeft() +{ + std::ostringstream ss; + ss << std::dec << (m_state.gas - m_state.gasCost); + return QString::fromStdString(ss.str()); +} + +QString DebuggingStateWrapper::gasCost() +{ + std::ostringstream ss; + ss << std::dec << m_state.gasCost; + return QString::fromStdString(ss.str()); +} + +QString DebuggingStateWrapper::gas() +{ + std::ostringstream ss; + ss << std::dec << m_state.gas; + return QString::fromStdString(ss.str()); +} + QString DebuggingStateWrapper::debugStack() { QString stack; @@ -99,11 +119,10 @@ QStringList DebuggingStateWrapper::levels() QStringList levelsStr; for (unsigned i = 0; i <= m_state.levels.size(); ++i) { - DebuggingState const& s = i ? *m_state.levels[m_state.levels.size() - i] : m_state; std::ostringstream out; out << m_state.cur.abridged(); if (i) - out << " " << instructionInfo(m_state.inst).name << " @0x" << hex << m_state.curPC; + out << " " << instructionInfo(m_state.inst).name << " @0x" << std::hex << m_state.curPC; levelsStr.append(QString::fromStdString(out.str())); } return levelsStr; @@ -112,14 +131,14 @@ QStringList DebuggingStateWrapper::levels() QString DebuggingStateWrapper::headerInfo() { std::ostringstream ss; - ss << dec << " STEP: " << m_state.steps << " | PC: 0x" << hex << m_state.curPC << " : " << dev::eth::instructionInfo(m_state.inst).name << " | ADDMEM: " << dec << m_state.newMemSize << " words | COST: " << dec << m_state.gasCost << " | GAS: " << dec << m_state.gas; + ss << std::dec << " " << QApplication::tr("STEP").toStdString() << " : " << m_state.steps << " | PC: 0x" << std::hex << m_state.curPC << " : " << dev::eth::instructionInfo(m_state.inst).name << " | ADDMEM: " << std::dec << m_state.newMemSize << " " << QApplication::tr("words").toStdString() << " | " << QApplication::tr("COST").toStdString() << " : " << std::dec << m_state.gasCost << " | " << QApplication::tr("GAS").toStdString() << " : " << std::dec << m_state.gas; return QString::fromStdString(ss.str()); } QString DebuggingStateWrapper::endOfDebug() { if (m_state.gasCost > m_state.gas) - return "OUT-OF-GAS"; + return QApplication::tr("OUT-OF-GAS"); else if (m_state.inst == Instruction::RETURN && m_state.stack.size() >= 2) { unsigned from = (unsigned)m_state.stack.back(); @@ -128,12 +147,12 @@ QString DebuggingStateWrapper::endOfDebug() bytes out(size, 0); for (; o < size && from + o < m_state.memory.size(); ++o) out[o] = m_state.memory[from + o]; - return "RETURN " + QString::fromStdString(dev::memDump(out, 16, false)); + return QApplication::tr("RETURN") + " " + QString::fromStdString(dev::memDump(out, 16, false)); } else if (m_state.inst == Instruction::STOP) - return "STOP"; + return QApplication::tr("STOP"); else if (m_state.inst == Instruction::SUICIDE && m_state.stack.size() >= 1) - return "SUICIDE 0x" + QString::fromStdString(toString(right160(m_state.stack.back()))); + return QApplication::tr("SUICIDE") + " 0x" + QString::fromStdString(toString(right160(m_state.stack.back()))); else - return "EXCEPTION"; + return QApplication::tr("EXCEPTION"); } diff --git a/mix/DebuggingStateWrapper.h b/mix/DebuggingStateWrapper.h index 09089fe58..d91d3d69c 100644 --- a/mix/DebuggingStateWrapper.h +++ b/mix/DebuggingStateWrapper.h @@ -99,8 +99,9 @@ class DebuggingStateWrapper: public QObject Q_OBJECT Q_PROPERTY(int step READ step) Q_PROPERTY(int curPC READ curPC) - Q_PROPERTY(int gasCost READ gasCost) - Q_PROPERTY(int gas READ gas) + Q_PROPERTY(QString gasCost READ gasCost) + Q_PROPERTY(QString gas READ gas) + Q_PROPERTY(QString gasLeft READ gasLeft) Q_PROPERTY(QString debugStack READ debugStack) Q_PROPERTY(QString debugStorage READ debugStorage) Q_PROPERTY(QString debugMemory READ debugMemory) @@ -113,8 +114,9 @@ public: DebuggingStateWrapper(bytes _code, bytes _data, QObject* _parent): QObject(_parent), m_code(_code), m_data(_data) {} int step() { return (int)m_state.steps; } int curPC() { return (int)m_state.curPC; } - int gasCost() { return (int)m_state.gasCost; } - int gas() { return (int)m_state.gas; } + QString gasLeft(); + QString gasCost(); + QString gas(); QString debugStack(); QString debugStorage(); QString debugMemory(); diff --git a/mix/qml/js/Debugger.js b/mix/qml/js/Debugger.js index ddaa362a6..5cd88d726 100644 --- a/mix/qml/js/Debugger.js +++ b/mix/qml/js/Debugger.js @@ -57,7 +57,6 @@ function endOfDebug() debugStorageTxt.text = ""; debugCallDataTxt.text = ""; debugStackTxt.text = ""; - debugMemoryTxt.text = state.endOfDebug - var gascost = state.gas - state.gasCost; - headerInfoLabel.text = "EXIT | GAS: " + gascost; + debugMemoryTxt.text = state.endOfDebug; + headerInfoLabel.text = "EXIT | GAS: " + state.gasLeft; } From f42f24165bc9f2385d5d9779eb540fd86acee87b Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 15 Dec 2014 10:43:22 +0100 Subject: [PATCH 195/277] Bugfix: Avoid accessing temporary after its lifetime. --- eth/main.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/eth/main.cpp b/eth/main.cpp index 49eac8876..1520e86c4 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -441,9 +441,8 @@ int main(int argc, char** argv) #endif else if (cmd == "address") { - cout << "Current address:" << endl; - const char* addchr = toHex(us.address().asArray()).c_str(); - cout << addchr << endl; + cout << "Current address:" << endl + << toHex(us.address().asArray()) << endl; } else if (cmd == "secret") { From 5026c5855ded326a5ea7e675d8c084ccda88c8ee Mon Sep 17 00:00:00 2001 From: Christian Date: Fri, 12 Dec 2014 16:49:26 +0100 Subject: [PATCH 196/277] Create contracts. --- libsolidity/AST.cpp | 38 ++++++++++++++++++++++++++---- libsolidity/AST.h | 28 ++++++++++++++++++++++ libsolidity/ASTForward.h | 1 + libsolidity/ASTPrinter.cpp | 13 ++++++++++ libsolidity/ASTPrinter.h | 2 ++ libsolidity/ASTVisitor.h | 4 ++++ libsolidity/AST_accept.h | 20 ++++++++++++++++ libsolidity/Compiler.cpp | 17 ++++++++----- libsolidity/Compiler.h | 6 +++-- libsolidity/CompilerContext.cpp | 8 +++++++ libsolidity/CompilerContext.h | 12 +++++++--- libsolidity/CompilerStack.cpp | 6 ++++- libsolidity/CompilerStack.h | 2 +- libsolidity/ExpressionCompiler.cpp | 38 ++++++++++++++++++++++++++++++ libsolidity/ExpressionCompiler.h | 1 + libsolidity/InterfaceHandler.cpp | 8 +++---- libsolidity/InterfaceHandler.h | 8 +++---- libsolidity/Parser.cpp | 12 +++++++++- libsolidity/Types.cpp | 13 ++++++++++ libsolidity/Types.h | 11 +++++++-- libsolidity/grammar.txt | 3 ++- test/solidityCompiler.cpp | 2 +- 22 files changed, 222 insertions(+), 31 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 8174d138a..3fcf8ba0b 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -54,6 +54,14 @@ vector ContractDefinition::getInterfaceFunctions() co return exportedFunctions; } +FunctionDefinition const* ContractDefinition::getConstructor() const +{ + for (ASTPointer const& f: m_definedFunctions) + if (f->getName() == getName()) + return f.get(); + return nullptr; +} + void StructDefinition::checkMemberTypes() const { for (ASTPointer const& member: getMembers()) @@ -235,13 +243,12 @@ void FunctionCall::checkTypeRequirements() BOOST_THROW_EXCEPTION(createTypeError("Explicit type conversion not allowed.")); m_type = type.getActualType(); } - else + else if (FunctionType const* functionType = dynamic_cast(expressionType)) { //@todo would be nice to create a struct type from the arguments // and then ask if that is implicitly convertible to the struct represented by the // function parameters - FunctionType const& functionType = dynamic_cast(*expressionType); - TypePointers const& parameterTypes = functionType.getParameterTypes(); + TypePointers const& parameterTypes = functionType->getParameterTypes(); if (parameterTypes.size() != m_arguments.size()) BOOST_THROW_EXCEPTION(createTypeError("Wrong argument count for function call.")); for (size_t i = 0; i < m_arguments.size(); ++i) @@ -249,11 +256,13 @@ void FunctionCall::checkTypeRequirements() BOOST_THROW_EXCEPTION(createTypeError("Invalid type for argument in function call.")); // @todo actually the return type should be an anonymous struct, // but we change it to the type of the first return value until we have structs - if (functionType.getReturnParameterTypes().empty()) + if (functionType->getReturnParameterTypes().empty()) m_type = make_shared(); else - m_type = functionType.getReturnParameterTypes().front(); + m_type = functionType->getReturnParameterTypes().front(); } + else + BOOST_THROW_EXCEPTION(createTypeError("Type is not callable.")); } bool FunctionCall::isTypeConversion() const @@ -261,6 +270,25 @@ bool FunctionCall::isTypeConversion() const return m_expression->getType()->getCategory() == Type::Category::TYPE; } +void NewExpression::checkTypeRequirements() +{ + m_contractName->checkTypeRequirements(); + for (ASTPointer const& argument: m_arguments) + argument->checkTypeRequirements(); + + m_contract = dynamic_cast(m_contractName->getReferencedDeclaration()); + if (!m_contract) + BOOST_THROW_EXCEPTION(createTypeError("Identifier is not a contract.")); + shared_ptr type = make_shared(*m_contract); + m_type = type; + TypePointers const& parameterTypes = type->getConstructorType()->getParameterTypes(); + if (parameterTypes.size() != m_arguments.size()) + BOOST_THROW_EXCEPTION(createTypeError("Wrong argument count for constructor call.")); + for (size_t i = 0; i < m_arguments.size(); ++i) + if (!m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameterTypes[i])) + BOOST_THROW_EXCEPTION(createTypeError("Invalid type for argument in constructor call.")); +} + void MemberAccess::checkTypeRequirements() { m_expression->checkTypeRequirements(); diff --git a/libsolidity/AST.h b/libsolidity/AST.h index 19c4b4275..3a15bbebe 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -181,6 +181,9 @@ public: /// Returns the functions that make up the calling interface in the intended order. std::vector getInterfaceFunctions() const; + /// Returns the constructor or nullptr if no constructor was specified + FunctionDefinition const* getConstructor() const; + private: std::vector> m_definedStructs; std::vector> m_stateVariables; @@ -740,6 +743,31 @@ private: std::vector> m_arguments; }; +/** + * Expression that creates a new contract, e.g. "new SomeContract(1, 2)". + */ +class NewExpression: public Expression +{ +public: + NewExpression(Location const& _location, ASTPointer const& _contractName, + std::vector> const& _arguments): + Expression(_location), m_contractName(_contractName), m_arguments(_arguments) {} + virtual void accept(ASTVisitor& _visitor) override; + virtual void accept(ASTConstVisitor& _visitor) const override; + virtual void checkTypeRequirements() override; + + std::vector> getArguments() const { return {m_arguments.begin(), m_arguments.end()}; } + + /// Returns the referenced contract. Can only be called after type checking. + ContractDefinition const* getContract() const { return m_contract; } + +private: + ASTPointer m_contractName; + std::vector> m_arguments; + + ContractDefinition const* m_contract = nullptr; +}; + /** * Access to a member of an object. Example: x.name */ diff --git a/libsolidity/ASTForward.h b/libsolidity/ASTForward.h index 8b4bac1ce..d6c4c9f44 100644 --- a/libsolidity/ASTForward.h +++ b/libsolidity/ASTForward.h @@ -62,6 +62,7 @@ class Assignment; class UnaryOperation; class BinaryOperation; class FunctionCall; +class NewExpression; class MemberAccess; class IndexAccess; class PrimaryExpression; diff --git a/libsolidity/ASTPrinter.cpp b/libsolidity/ASTPrinter.cpp index eddb51340..970822a9a 100644 --- a/libsolidity/ASTPrinter.cpp +++ b/libsolidity/ASTPrinter.cpp @@ -226,6 +226,14 @@ bool ASTPrinter::visit(FunctionCall const& _node) return goDeeper(); } +bool ASTPrinter::visit(NewExpression const& _node) +{ + writeLine("NewExpression"); + printType(_node); + printSourcePart(_node); + return goDeeper(); +} + bool ASTPrinter::visit(MemberAccess const& _node) { writeLine("MemberAccess to member " + _node.getMemberName()); @@ -402,6 +410,11 @@ void ASTPrinter::endVisit(FunctionCall const&) m_indentation--; } +void ASTPrinter::endVisit(NewExpression const&) +{ + m_indentation--; +} + void ASTPrinter::endVisit(MemberAccess const&) { m_indentation--; diff --git a/libsolidity/ASTPrinter.h b/libsolidity/ASTPrinter.h index 5a9187154..15b65e3f0 100644 --- a/libsolidity/ASTPrinter.h +++ b/libsolidity/ASTPrinter.h @@ -67,6 +67,7 @@ public: bool visit(UnaryOperation const& _node) override; bool visit(BinaryOperation const& _node) override; bool visit(FunctionCall const& _node) override; + bool visit(NewExpression const& _node) override; bool visit(MemberAccess const& _node) override; bool visit(IndexAccess const& _node) override; bool visit(PrimaryExpression const& _node) override; @@ -99,6 +100,7 @@ public: void endVisit(UnaryOperation const&) override; void endVisit(BinaryOperation const&) override; void endVisit(FunctionCall const&) override; + void endVisit(NewExpression const&) override; void endVisit(MemberAccess const&) override; void endVisit(IndexAccess const&) override; void endVisit(PrimaryExpression const&) override; diff --git a/libsolidity/ASTVisitor.h b/libsolidity/ASTVisitor.h index 4e1a49458..5728cd3d0 100644 --- a/libsolidity/ASTVisitor.h +++ b/libsolidity/ASTVisitor.h @@ -68,6 +68,7 @@ public: virtual bool visit(UnaryOperation&) { return true; } virtual bool visit(BinaryOperation&) { return true; } virtual bool visit(FunctionCall&) { return true; } + virtual bool visit(NewExpression&) { return true; } virtual bool visit(MemberAccess&) { return true; } virtual bool visit(IndexAccess&) { return true; } virtual bool visit(PrimaryExpression&) { return true; } @@ -102,6 +103,7 @@ public: virtual void endVisit(UnaryOperation&) { } virtual void endVisit(BinaryOperation&) { } virtual void endVisit(FunctionCall&) { } + virtual void endVisit(NewExpression&) { } virtual void endVisit(MemberAccess&) { } virtual void endVisit(IndexAccess&) { } virtual void endVisit(PrimaryExpression&) { } @@ -140,6 +142,7 @@ public: virtual bool visit(UnaryOperation const&) { return true; } virtual bool visit(BinaryOperation const&) { return true; } virtual bool visit(FunctionCall const&) { return true; } + virtual bool visit(NewExpression const&) { return true; } virtual bool visit(MemberAccess const&) { return true; } virtual bool visit(IndexAccess const&) { return true; } virtual bool visit(PrimaryExpression const&) { return true; } @@ -174,6 +177,7 @@ public: virtual void endVisit(UnaryOperation const&) { } virtual void endVisit(BinaryOperation const&) { } virtual void endVisit(FunctionCall const&) { } + virtual void endVisit(NewExpression const&) { } virtual void endVisit(MemberAccess const&) { } virtual void endVisit(IndexAccess const&) { } virtual void endVisit(PrimaryExpression const&) { } diff --git a/libsolidity/AST_accept.h b/libsolidity/AST_accept.h index 173273c6d..e0454d33e 100644 --- a/libsolidity/AST_accept.h +++ b/libsolidity/AST_accept.h @@ -419,6 +419,26 @@ void FunctionCall::accept(ASTConstVisitor& _visitor) const _visitor.endVisit(*this); } +void NewExpression::accept(ASTVisitor& _visitor) +{ + if (_visitor.visit(*this)) + { + m_contractName->accept(_visitor); + listAccept(m_arguments, _visitor); + } + _visitor.endVisit(*this); +} + +void NewExpression::accept(ASTConstVisitor& _visitor) const +{ + if (_visitor.visit(*this)) + { + m_contractName->accept(_visitor); + listAccept(m_arguments, _visitor); + } + _visitor.endVisit(*this); +} + void MemberAccess::accept(ASTVisitor& _visitor) { if (_visitor.visit(*this)) diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index 258336917..48d8be88a 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -33,9 +33,11 @@ using namespace std; namespace dev { namespace solidity { -void Compiler::compileContract(ContractDefinition const& _contract, vector const& _magicGlobals) +void Compiler::compileContract(ContractDefinition const& _contract, vector const& _magicGlobals, + map const& _contracts) { m_context = CompilerContext(); // clear it just in case + m_context.setCompiledContracts(_contracts); for (MagicVariableDeclaration const* variable: _magicGlobals) m_context.addMagicGlobal(*variable); @@ -50,12 +52,14 @@ void Compiler::compileContract(ContractDefinition const& _contract, vectorgetName() != _contract.getName()) // don't add the constructor here function->accept(*this); - packIntoContractCreator(_contract); + packIntoContractCreator(_contract, _contracts); } -void Compiler::packIntoContractCreator(ContractDefinition const& _contract) +void Compiler::packIntoContractCreator(ContractDefinition const& _contract, + map const& _contracts) { CompilerContext runtimeContext; + runtimeContext.setCompiledContracts(_contracts); swap(m_context, runtimeContext); registerStateVariables(_contract); @@ -67,11 +71,14 @@ void Compiler::packIntoContractCreator(ContractDefinition const& _contract) constructor = function.get(); break; } + eth::AssemblyItem sub = m_context.addSubroutine(runtimeContext.getAssembly()); + // stack contains sub size if (constructor) { eth::AssemblyItem returnTag = m_context.pushNewTag(); m_context.addFunction(*constructor); // note that it cannot be called due to syntactic reasons - //@todo copy constructor arguments from calldata to memory prior to this + // copy constructor arguments + //@todo ask assembly for the size of the current program //@todo calling other functions inside the constructor should either trigger a parse error //or we should copy them here (register them above and call "accept") - detecting which // functions are referenced / called needs to be done in a recursive way. @@ -81,8 +88,6 @@ void Compiler::packIntoContractCreator(ContractDefinition const& _contract) m_context << returnTag; } - eth::AssemblyItem sub = m_context.addSubroutine(runtimeContext.getAssembly()); - // stack contains sub size m_context << eth::Instruction::DUP1 << sub << u256(0) << eth::Instruction::CODECOPY; m_context << u256(0) << eth::Instruction::RETURN; } diff --git a/libsolidity/Compiler.h b/libsolidity/Compiler.h index 639e98410..57e40cdae 100644 --- a/libsolidity/Compiler.h +++ b/libsolidity/Compiler.h @@ -32,14 +32,16 @@ class Compiler: private ASTConstVisitor public: explicit Compiler(bool _optimize = false): m_optimize(_optimize), m_returnTag(m_context.newTag()) {} - void compileContract(ContractDefinition const& _contract, std::vector const& _magicGlobals); + void compileContract(ContractDefinition const& _contract, std::vector const& _magicGlobals, + std::map const& _contracts); bytes getAssembledBytecode() { return m_context.getAssembledBytecode(m_optimize); } void streamAssembly(std::ostream& _stream) const { m_context.streamAssembly(_stream); } private: /// Creates a new compiler context / assembly, packs the current code into the data part and /// adds the constructor code. - void packIntoContractCreator(ContractDefinition const& _contract); + void packIntoContractCreator(ContractDefinition const& _contract, + std::map const& _contracts); void appendFunctionSelector(ContractDefinition const& _contract); /// Creates code that unpacks the arguments for the given function, from memory if /// @a _fromMemory is true, otherwise from call data. @returns the size of the data in bytes. diff --git a/libsolidity/CompilerContext.cpp b/libsolidity/CompilerContext.cpp index cd22c4e8b..47401436a 100644 --- a/libsolidity/CompilerContext.cpp +++ b/libsolidity/CompilerContext.cpp @@ -62,6 +62,14 @@ void CompilerContext::addFunction(FunctionDefinition const& _function) m_functionEntryLabels.insert(std::make_pair(&_function, m_asm.newTag())); } +bytes const& CompilerContext::getCompiledContract(const ContractDefinition& _contract) const +{ + auto ret = m_compiledContracts.find(&_contract); + if (asserts(ret != m_compiledContracts.end())) + BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Compiled contract not found.")); + return *ret->second; +} + bool CompilerContext::isLocalVariable(Declaration const* _declaration) const { return m_localVariables.count(_declaration) > 0; diff --git a/libsolidity/CompilerContext.h b/libsolidity/CompilerContext.h index 652e65a63..99f5ae94c 100644 --- a/libsolidity/CompilerContext.h +++ b/libsolidity/CompilerContext.h @@ -39,8 +39,6 @@ namespace solidity { class CompilerContext { public: - CompilerContext(): m_stateVariablesSize(0) {} - void addMagicGlobal(MagicVariableDeclaration const& _declaration); void addStateVariable(VariableDeclaration const& _declaration); void startNewFunction() { m_localVariables.clear(); m_asm.setDeposit(0); } @@ -48,6 +46,9 @@ public: void addAndInitializeVariable(VariableDeclaration const& _declaration); void addFunction(FunctionDefinition const& _function); + void setCompiledContracts(std::map const& _contracts) { m_compiledContracts = _contracts; } + bytes const& getCompiledContract(ContractDefinition const& _contract) const; + void adjustStackOffset(int _adjustment) { m_asm.adjustDeposit(_adjustment); } bool isMagicGlobal(Declaration const* _declaration) const { return m_magicGlobals.count(_declaration); } @@ -80,6 +81,8 @@ public: /// Adds a subroutine to the code (in the data section) and pushes its size (via a tag) /// on the stack. @returns the assembly item corresponding to the pushed subroutine, i.e. its offset. eth::AssemblyItem addSubroutine(eth::Assembly const& _assembly) { return m_asm.appendSubSize(_assembly); } + /// Adds data to the data section, pushes a reference to the stack + eth::AssemblyItem appendData(bytes const& _data) { return m_asm.append(_data); } /// Append elements to the current instruction list and adjust @a m_stackOffset. CompilerContext& operator<<(eth::AssemblyItem const& _item) { m_asm.append(_item); return *this; } @@ -90,13 +93,16 @@ public: eth::Assembly const& getAssembly() const { return m_asm; } void streamAssembly(std::ostream& _stream) const { _stream << m_asm; } bytes getAssembledBytecode(bool _optimize = false) { return m_asm.optimise(_optimize).assemble(); } + private: eth::Assembly m_asm; /// Magic global variables like msg, tx or this, distinguished by type. std::set m_magicGlobals; + /// Other already compiled contracts to be used in contract creation calls. + std::map m_compiledContracts; /// Size of the state variables, offset of next variable to be added. - u256 m_stateVariablesSize; + u256 m_stateVariablesSize = 0; /// Storage offsets of state variables std::map m_stateVariables; /// Offsets of local variables on the stack (relative to stack base). diff --git a/libsolidity/CompilerStack.cpp b/libsolidity/CompilerStack.cpp index 7aaa79b1c..23f5fd68f 100644 --- a/libsolidity/CompilerStack.cpp +++ b/libsolidity/CompilerStack.cpp @@ -96,16 +96,20 @@ void CompilerStack::compile(bool _optimize) { if (!m_parseSuccessful) parse(); + + map contractBytecode; for (Source const* source: m_sourceOrder) for (ASTPointer const& node: source->ast->getNodes()) if (ContractDefinition* contract = dynamic_cast(node.get())) { m_globalContext->setCurrentContract(*contract); shared_ptr compiler = make_shared(_optimize); - compiler->compileContract(*contract, m_globalContext->getMagicVariables()); + compiler->compileContract(*contract, m_globalContext->getMagicVariables(), + contractBytecode); Contract& compiledContract = m_contracts[contract->getName()]; compiledContract.bytecode = compiler->getAssembledBytecode(); compiledContract.compiler = move(compiler); + contractBytecode[compiledContract.contract] = &compiledContract.bytecode; } } diff --git a/libsolidity/CompilerStack.h b/libsolidity/CompilerStack.h index b6c34f1ac..5ad6f0a60 100644 --- a/libsolidity/CompilerStack.h +++ b/libsolidity/CompilerStack.h @@ -108,7 +108,7 @@ private: struct Contract { - ContractDefinition* contract; + ContractDefinition const* contract; std::shared_ptr compiler; bytes bytecode; std::shared_ptr interfaceHandler; diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index f872e0581..743503bbf 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -279,6 +279,44 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) return false; } +bool ExpressionCompiler::visit(NewExpression const& _newExpression) +{ + ContractType const* type = dynamic_cast(_newExpression.getType().get()); + if (asserts(type)) + BOOST_THROW_EXCEPTION(InternalCompilerError()); + TypePointers const& types = type->getConstructorType()->getParameterTypes(); + vector> arguments = _newExpression.getArguments(); + if (asserts(arguments.size() == types.size())) + BOOST_THROW_EXCEPTION(InternalCompilerError()); + + // copy the contracts code into memory + bytes const& bytecode = m_context.getCompiledContract(*_newExpression.getContract()); + m_context << u256(bytecode.size()); + //@todo could be done by actually appending the Assembly, but then we probably need to compile + // multiple times. Will revisit once external fuctions are inlined. + m_context.appendData(bytecode); + //@todo copy to memory position 0, shift as soon as we use memory + m_context << u256(0) << eth::Instruction::CODECOPY; + + unsigned dataOffset = bytecode.size(); + for (unsigned i = 0; i < arguments.size(); ++i) + { + arguments[i]->accept(*this); + appendTypeConversion(*arguments[i]->getType(), *types[i]); + unsigned const numBytes = types[i]->getCalldataEncodedSize(); + if (numBytes > 32) + BOOST_THROW_EXCEPTION(CompilerError() + << errinfo_sourceLocation(arguments[i]->getLocation()) + << errinfo_comment("Type " + types[i]->toString() + " not yet supported.")); + bool const leftAligned = types[i]->getCategory() == Type::Category::STRING; + CompilerUtils(m_context).storeInMemory(dataOffset, numBytes, leftAligned); + dataOffset += numBytes; + } + // size, offset, endowment + m_context << u256(dataOffset) << u256(0) << u256(0) << eth::Instruction::CREATE; + return false; +} + void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) { ASTString const& member = _memberAccess.getMemberName(); diff --git a/libsolidity/ExpressionCompiler.h b/libsolidity/ExpressionCompiler.h index 0bba211ce..67b16aac0 100644 --- a/libsolidity/ExpressionCompiler.h +++ b/libsolidity/ExpressionCompiler.h @@ -60,6 +60,7 @@ private: virtual void endVisit(UnaryOperation const& _unaryOperation) override; virtual bool visit(BinaryOperation const& _binaryOperation) override; virtual bool visit(FunctionCall const& _functionCall) override; + virtual bool visit(NewExpression const& _newExpression) override; virtual void endVisit(MemberAccess const& _memberAccess) override; virtual bool visit(IndexAccess const& _indexAccess) override; virtual void endVisit(Identifier const& _identifier) override; diff --git a/libsolidity/InterfaceHandler.cpp b/libsolidity/InterfaceHandler.cpp index f26088afa..1310f504a 100644 --- a/libsolidity/InterfaceHandler.cpp +++ b/libsolidity/InterfaceHandler.cpp @@ -15,7 +15,7 @@ InterfaceHandler::InterfaceHandler() m_lastTag = DocTagType::NONE; } -std::unique_ptr InterfaceHandler::getDocumentation(ContractDefinition& _contractDef, +std::unique_ptr InterfaceHandler::getDocumentation(ContractDefinition const& _contractDef, DocumentationType _type) { switch(_type) @@ -32,7 +32,7 @@ std::unique_ptr InterfaceHandler::getDocumentation(ContractDefiniti return nullptr; } -std::unique_ptr InterfaceHandler::getABIInterface(ContractDefinition& _contractDef) +std::unique_ptr InterfaceHandler::getABIInterface(ContractDefinition const& _contractDef) { Json::Value methods(Json::arrayValue); @@ -63,7 +63,7 @@ std::unique_ptr InterfaceHandler::getABIInterface(ContractDefinitio return std::unique_ptr(new std::string(m_writer.write(methods))); } -std::unique_ptr InterfaceHandler::getUserDocumentation(ContractDefinition& _contractDef) +std::unique_ptr InterfaceHandler::getUserDocumentation(ContractDefinition const& _contractDef) { Json::Value doc; Json::Value methods(Json::objectValue); @@ -88,7 +88,7 @@ std::unique_ptr InterfaceHandler::getUserDocumentation(ContractDefi return std::unique_ptr(new std::string(m_writer.write(doc))); } -std::unique_ptr InterfaceHandler::getDevDocumentation(ContractDefinition& _contractDef) +std::unique_ptr InterfaceHandler::getDevDocumentation(ContractDefinition const& _contractDef) { // LTODO: Somewhere in this function warnings for mismatch of param names // should be thrown diff --git a/libsolidity/InterfaceHandler.h b/libsolidity/InterfaceHandler.h index b1cd4b562..d271a6697 100644 --- a/libsolidity/InterfaceHandler.h +++ b/libsolidity/InterfaceHandler.h @@ -67,23 +67,23 @@ public: /// types provided by @c DocumentationType /// @return A unique pointer contained string with the json /// representation of provided type - std::unique_ptr getDocumentation(ContractDefinition& _contractDef, + std::unique_ptr getDocumentation(ContractDefinition const& _contractDef, DocumentationType _type); /// Get the ABI Interface of the contract /// @param _contractDef The contract definition /// @return A unique pointer contained string with the json /// representation of the contract's ABI Interface - std::unique_ptr getABIInterface(ContractDefinition& _contractDef); + std::unique_ptr getABIInterface(ContractDefinition const& _contractDef); /// Get the User documentation of the contract /// @param _contractDef The contract definition /// @return A unique pointer contained string with the json /// representation of the contract's user documentation - std::unique_ptr getUserDocumentation(ContractDefinition& _contractDef); + std::unique_ptr getUserDocumentation(ContractDefinition const& _contractDef); /// Get the Developer's documentation of the contract /// @param _contractDef The contract definition /// @return A unique pointer contained string with the json /// representation of the contract's developer documentation - std::unique_ptr getDevDocumentation(ContractDefinition& _contractDef); + std::unique_ptr getDevDocumentation(ContractDefinition const& _contractDef); private: void resetUser(); diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index b678b2fc0..21651eb14 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -437,7 +437,17 @@ ASTPointer Parser::parseUnaryExpression() { ASTNodeFactory nodeFactory(*this); Token::Value token = m_scanner->getCurrentToken(); - if (Token::isUnaryOp(token) || Token::isCountOp(token)) + if (token == Token::NEW) + { + expectToken(Token::NEW); + ASTPointer contractName = ASTNodeFactory(*this).createNode(expectIdentifierToken()); + expectToken(Token::LPAREN); + vector> arguments(parseFunctionCallArguments()); + expectToken(Token::RPAREN); + nodeFactory.markEndPosition(); + return nodeFactory.createNode(contractName, arguments); + } + else if (Token::isUnaryOp(token) || Token::isCountOp(token)) { // prefix expression m_scanner->next(); diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index c2d488418..f1cd7c228 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -310,6 +310,19 @@ MemberList const& ContractType::getMembers() const return *m_members; } +shared_ptr const& ContractType::getConstructorType() const +{ + if (!m_constructorType) + { + FunctionDefinition const* constr = m_contract.getConstructor(); + if (constr) + m_constructorType = make_shared(*constr); + else + m_constructorType = make_shared(TypePointers(), TypePointers()); + } + return m_constructorType; +} + unsigned ContractType::getFunctionIndex(string const& _functionName) const { unsigned index = 0; diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 807e60c74..48539a1d7 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -39,6 +39,7 @@ namespace solidity // @todo realMxN, dynamic strings, text, arrays class Type; // forward +class FunctionType; // forward using TypePointer = std::shared_ptr; using TypePointers = std::vector; @@ -249,10 +250,16 @@ public: virtual MemberList const& getMembers() const override; + /// Returns the function type of the constructor. Note that the location part of the function type + /// is not used, as this type cannot be the type of a variable or expression. + std::shared_ptr const& getConstructorType() const; + unsigned getFunctionIndex(std::string const& _functionName) const; private: ContractDefinition const& m_contract; + /// Type of the constructor, @see getConstructorType. Lazily initialized. + mutable std::shared_ptr m_constructorType; /// List of member types, will be lazy-initialized because of recursive references. mutable std::unique_ptr m_members; }; @@ -339,8 +346,8 @@ public: virtual std::string toString() const override; virtual bool canLiveOutsideStorage() const override { return false; } - TypePointer getKeyType() const { return m_keyType; } - TypePointer getValueType() const { return m_valueType; } + TypePointer const& getKeyType() const { return m_keyType; } + TypePointer const& getValueType() const { return m_valueType; } private: TypePointer m_keyType; diff --git a/libsolidity/grammar.txt b/libsolidity/grammar.txt index c0ab06074..793e91882 100644 --- a/libsolidity/grammar.txt +++ b/libsolidity/grammar.txt @@ -25,11 +25,12 @@ Break = 'break' ';' Return = 'return' Expression? ';' VariableDefinition = VariableDeclaration ( = Expression )? ';' -Expression = Assignment | UnaryOperation | BinaryOperation | FunctionCall | IndexAccess | +Expression = Assignment | UnaryOperation | BinaryOperation | FunctionCall | NewExpression | IndexAccess | MemberAccess | PrimaryExpression // The expression syntax is actually much more complicated Assignment = Expression (AssignmentOp Expression) FunctionCall = Expression '(' ( Expression ( ',' Expression )* ) ')' +NewExpression = 'new' Identifier '(' ( Expression ( ',' Expression )* ) ')' MemberAccess = Expression '.' Identifier IndexAccess = Expression '[' Expresison ']' PrimaryExpression = Identifier | NumberLiteral | StringLiteral | ElementaryTypeName | '(' Expression ')' diff --git a/test/solidityCompiler.cpp b/test/solidityCompiler.cpp index eae8f3142..29f61454a 100644 --- a/test/solidityCompiler.cpp +++ b/test/solidityCompiler.cpp @@ -56,7 +56,7 @@ bytes compileContract(const string& _sourceCode) BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract)); Compiler compiler; - compiler.compileContract(*contract, {}); + compiler.compileContract(*contract, {}, {}); // debug //compiler.streamAssembly(cout); return compiler.getAssembledBytecode(); From 7801b87ddb2b21f32af1495e367f11bc99c88766 Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 15 Dec 2014 12:59:17 +0100 Subject: [PATCH 197/277] Packing and unpacking of constructor arguments. --- libevmcore/Assembly.cpp | 21 ++++++++++++++++++++- libevmcore/Assembly.h | 5 ++++- libsolidity/Compiler.cpp | 16 ++++++++++++---- libsolidity/CompilerContext.h | 2 ++ test/solidityEndToEndTest.cpp | 26 ++++++++++++++++++++++++++ 5 files changed, 64 insertions(+), 6 deletions(-) diff --git a/libevmcore/Assembly.cpp b/libevmcore/Assembly.cpp index 059810af8..b78f03035 100644 --- a/libevmcore/Assembly.cpp +++ b/libevmcore/Assembly.cpp @@ -39,6 +39,7 @@ unsigned AssemblyItem::bytesRequired(unsigned _addressLength) const case Push: return 1 + max(1, dev::bytesRequired(m_data)); case PushSubSize: + case PushProgramSize: return 4; // worst case: a 16MB program case PushTag: case PushData: @@ -59,7 +60,7 @@ int AssemblyItem::deposit() const { case Operation: return instructionInfo((Instruction)(byte)m_data).ret - instructionInfo((Instruction)(byte)m_data).args; - case Push: case PushString: case PushTag: case PushData: case PushSub: case PushSubSize: + case Push: case PushString: case PushTag: case PushData: case PushSub: case PushSubSize: case PushProgramSize: return 1; case Tag: return 0; @@ -146,6 +147,9 @@ ostream& dev::eth::operator<<(ostream& _out, AssemblyItemsConstRef _i) case PushSubSize: _out << " PUSHss[" << hex << h256(i.data()).abridged() << "]"; break; + case PushProgramSize: + _out << " PUSHSIZE"; + break; case NoOptimizeBegin: _out << " DoNotOptimze{{"; break; @@ -185,6 +189,9 @@ ostream& Assembly::streamRLP(ostream& _out, string const& _prefix) const case PushSubSize: _out << _prefix << " PUSH #[$" << h256(i.m_data).abridged() << "]" << endl; break; + case PushProgramSize: + _out << _prefix << " PUSHSIZE" << endl; + break; case Tag: _out << _prefix << "tag" << i.m_data << ": " << endl << _prefix << " JUMPDEST" << endl; break; @@ -303,6 +310,7 @@ Assembly& Assembly::optimise(bool _enable) { { PushString, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } }, { { PushSub, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } }, { { PushSubSize, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } }, + { { PushProgramSize, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } }, { { Push, PushTag, Instruction::JUMPI }, [](AssemblyItemsConstRef m) -> AssemblyItems { if (m[0].data()) return { m[1], Instruction::JUMP }; else return {}; } }, { { Instruction::ISZERO, Instruction::ISZERO }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } }, }; @@ -468,6 +476,7 @@ bytes Assembly::assemble() const vector tagPos(m_usedTags); map tagRef; multimap dataRef; + vector sizeRef; ///< Pointers to code locations where the size of the program is inserted unsigned bytesPerTag = dev::bytesRequired(totalBytes); byte tagPush = (byte)Instruction::PUSH1 - 1 + bytesPerTag; @@ -526,6 +535,11 @@ bytes Assembly::assemble() const toBigEndian(s, byr); break; } + case PushProgramSize: + ret.push_back(tagPush); + sizeRef.push_back(ret.size()); + ret.resize(ret.size() + bytesPerTag); + break; case Tag: tagPos[(unsigned)i.m_data] = ret.size(); ret.push_back((byte)Instruction::JUMPDEST); @@ -561,5 +575,10 @@ bytes Assembly::assemble() const } } } + for (unsigned pos: sizeRef) + { + bytesRef r(ret.data() + pos, bytesPerTag); + toBigEndian(ret.size(), r); + } return ret; } diff --git a/libevmcore/Assembly.h b/libevmcore/Assembly.h index 5523710d4..81e4a9ff7 100644 --- a/libevmcore/Assembly.h +++ b/libevmcore/Assembly.h @@ -32,7 +32,7 @@ namespace dev namespace eth { -enum AssemblyItemType { UndefinedItem, Operation, Push, PushString, PushTag, PushSub, PushSubSize, Tag, PushData, NoOptimizeBegin, NoOptimizeEnd }; +enum AssemblyItemType { UndefinedItem, Operation, Push, PushString, PushTag, PushSub, PushSubSize, PushProgramSize, Tag, PushData, NoOptimizeBegin, NoOptimizeEnd }; class Assembly; @@ -86,6 +86,9 @@ public: AssemblyItem const& append(std::string const& _data) { return append(newPushString(_data)); } AssemblyItem const& append(bytes const& _data) { return append(newData(_data)); } AssemblyItem appendSubSize(Assembly const& _a) { auto ret = newSub(_a); append(newPushSubSize(ret.data())); return ret; } + /// Pushes the final size of the current assembly itself. Use this when the code is modified + /// after compilation and CODESIZE is not an option. + void appendProgramSize() { append(AssemblyItem(PushProgramSize)); } AssemblyItem appendJump() { auto ret = append(newPushTag()); append(Instruction::JUMP); return ret; } AssemblyItem appendJumpI() { auto ret = append(newPushTag()); append(Instruction::JUMPI); return ret; } diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index 48d8be88a..f2877c1ce 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -77,12 +77,21 @@ void Compiler::packIntoContractCreator(ContractDefinition const& _contract, { eth::AssemblyItem returnTag = m_context.pushNewTag(); m_context.addFunction(*constructor); // note that it cannot be called due to syntactic reasons - // copy constructor arguments - //@todo ask assembly for the size of the current program + // copy constructor arguments from code to memory and then to stack, they are supplied after the actual program + unsigned argumentSize = 0; + for (ASTPointer const& var: constructor->getParameters()) + argumentSize += var->getType()->getCalldataEncodedSize(); + if (argumentSize > 0) + { + m_context << u256(argumentSize); + m_context.appendProgramSize(); + m_context << u256(1); // copy it to byte one as expected for ABI calls + m_context << eth::Instruction::CODECOPY; + appendCalldataUnpacker(*constructor, true); + } //@todo calling other functions inside the constructor should either trigger a parse error //or we should copy them here (register them above and call "accept") - detecting which // functions are referenced / called needs to be done in a recursive way. - appendCalldataUnpacker(*constructor, true); m_context.appendJumpTo(m_context.getFunctionEntryLabel(*constructor)); constructor->accept(*this); m_context << returnTag; @@ -135,7 +144,6 @@ unsigned Compiler::appendCalldataUnpacker(FunctionDefinition const& _function, b { // We do not check the calldata size, everything is zero-padded. unsigned dataOffset = 1; - //@todo this can be done more efficiently, saving some CALLDATALOAD calls for (ASTPointer const& var: _function.getParameters()) { diff --git a/libsolidity/CompilerContext.h b/libsolidity/CompilerContext.h index 99f5ae94c..795f447ab 100644 --- a/libsolidity/CompilerContext.h +++ b/libsolidity/CompilerContext.h @@ -81,6 +81,8 @@ public: /// Adds a subroutine to the code (in the data section) and pushes its size (via a tag) /// on the stack. @returns the assembly item corresponding to the pushed subroutine, i.e. its offset. eth::AssemblyItem addSubroutine(eth::Assembly const& _assembly) { return m_asm.appendSubSize(_assembly); } + /// Pushes the size of the final program + void appendProgramSize() { return m_asm.appendProgramSize(); } /// Adds data to the data section, pushes a reference to the stack eth::AssemblyItem appendData(bytes const& _data) { return m_asm.append(_data); } diff --git a/test/solidityEndToEndTest.cpp b/test/solidityEndToEndTest.cpp index 15722abe1..b6f63aa72 100644 --- a/test/solidityEndToEndTest.cpp +++ b/test/solidityEndToEndTest.cpp @@ -1012,6 +1012,32 @@ BOOST_AUTO_TEST_CASE(strings_in_calls) BOOST_CHECK(callContractFunction(0, bytes({0, 'a', 1})) == bytes({0, 'a', 0, 0, 0})); } +BOOST_AUTO_TEST_CASE(constructor_arguments) +{ + char const* sourceCode = R"( + contract Helper { + string3 name; + bool flag; + function Helper(string3 x, bool f) { + name = x; + flag = f; + } + function getName() returns (string3 ret) { return name; } + function getFlag() returns (bool ret) { return flag; } + } + contract Main { + Helper h; + function Main() { + h = new Helper("abc", true); + } + function getFlag() returns (bool ret) { return h.getFlag(); } + function getName() returns (string3 ret) { return h.getName(); } + })"; + compileAndRun(sourceCode, 0, "Main"); + BOOST_REQUIRE(callContractFunction(0) == bytes({0x01})); + BOOST_REQUIRE(callContractFunction(1) == bytes({'a', 'b', 'c'})); +} + BOOST_AUTO_TEST_SUITE_END() } From 1efde49fd7e1ef2f7b7cb573584311f98748e93f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 15 Dec 2014 15:13:57 +0100 Subject: [PATCH 198/277] Update usage of ExtVMFace in evmjit submodule --- evmjit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evmjit b/evmjit index b3a17341e..dbf8174fc 160000 --- a/evmjit +++ b/evmjit @@ -1 +1 @@ -Subproject commit b3a17341e4ee3f2af12270d92cf404293deefc73 +Subproject commit dbf8174fc6f8be9e6d1e62a627388fa23eb2308f From a3473ad88d39a1491d3b13da7efd11537eede1f1 Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 15 Dec 2014 16:09:50 +0100 Subject: [PATCH 199/277] Check that constructor does not have "returns" directive. --- libsolidity/AST.cpp | 11 +++++++++++ libsolidity/AST.h | 4 ++++ libsolidity/NameAndTypeResolver.cpp | 6 +----- test/solidityNameAndTypeResolution.cpp | 9 +++++++++ 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 3fcf8ba0b..5e344eadb 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -39,6 +39,17 @@ TypeError ASTNode::createTypeError(string const& _description) const return TypeError() << errinfo_sourceLocation(getLocation()) << errinfo_comment(_description); } +void ContractDefinition::checkTypeRequirements() +{ + FunctionDefinition const* constructor = getConstructor(); + if (constructor && !constructor->getReturnParameters().empty()) + BOOST_THROW_EXCEPTION(constructor->getReturnParameterList()->createTypeError( + "Non-empty \"returns\" directive for constructor.")); + + for (ASTPointer const& function: getDefinedFunctions()) + function->checkTypeRequirements(); +} + vector ContractDefinition::getInterfaceFunctions() const { vector exportedFunctions; diff --git a/libsolidity/AST.h b/libsolidity/AST.h index 3a15bbebe..72f96394f 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -174,6 +174,10 @@ public: std::vector> const& getStateVariables() const { return m_stateVariables; } std::vector> const& getDefinedFunctions() const { return m_definedFunctions; } + /// Checks that the constructor does not have a "returns" statement and calls + /// checkTypeRequirements on all its functions. + void checkTypeRequirements(); + /// @return A shared pointer of an ASTString. /// Can contain a nullptr in which case indicates absence of documentation ASTPointer const& getDocumentation() const { return m_documentation; } diff --git a/libsolidity/NameAndTypeResolver.cpp b/libsolidity/NameAndTypeResolver.cpp index 540b066eb..2ad276801 100644 --- a/libsolidity/NameAndTypeResolver.cpp +++ b/libsolidity/NameAndTypeResolver.cpp @@ -62,11 +62,7 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract) // First, the parameter types of all functions need to be resolved before we can check // the types, since it is possible to call functions that are only defined later // in the source. - for (ASTPointer const& function: _contract.getDefinedFunctions()) - { - m_currentScope = &m_scopes[function.get()]; - function->checkTypeRequirements(); - } + _contract.checkTypeRequirements(); m_currentScope = &m_scopes[nullptr]; } diff --git a/test/solidityNameAndTypeResolution.cpp b/test/solidityNameAndTypeResolution.cpp index 03eaebb3a..0ea6e51b9 100644 --- a/test/solidityNameAndTypeResolution.cpp +++ b/test/solidityNameAndTypeResolution.cpp @@ -284,6 +284,15 @@ BOOST_AUTO_TEST_CASE(assignment_to_struct) BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); } +BOOST_AUTO_TEST_CASE(returns_in_constructor) +{ + char const* text = "contract test {\n" + " function test() returns (uint a) {\n" + " }\n" + "}\n"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } From 592e60ec1742749ae4d81e8b24e472bcbe88582f Mon Sep 17 00:00:00 2001 From: ethdev Date: Mon, 15 Dec 2014 18:19:58 +0100 Subject: [PATCH 200/277] start of implementing windows debug --- cmake/EthDependencies.cmake | 4 ++++ libdevcore/CMakeLists.txt | 8 ++++---- solc/CMakeLists.txt | 4 ++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index ee93a5311..7ff225594 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -141,6 +141,10 @@ find_package(Boost 1.54.0 REQUIRED COMPONENTS thread date_time system regex chro message(" - boost header: ${Boost_INCLUDE_DIRS}") message(" - boost lib : ${Boost_LIBRARIES}") +message("debug ${Boost_SYSTEM_LIBRARY_DEBUG}") +message("release ${Boost_SYSTEM_LIBRARY_RELEASE}") +message("other ${Boost_SYSTEM_LIBRARY}") + if (APPLE) link_directories(/usr/local/lib) include_directories(/usr/local/include) diff --git a/libdevcore/CMakeLists.txt b/libdevcore/CMakeLists.txt index 001c568b5..ce8abcbb3 100644 --- a/libdevcore/CMakeLists.txt +++ b/libdevcore/CMakeLists.txt @@ -25,10 +25,10 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY_RELEASE}) -target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY_RELEASE}) -target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY_RELEASE}) -target_link_libraries(${EXECUTABLE} ${Boost_CHRONO_LIBRARY_RELEASE}) +target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${Boost_CHRONO_LIBRARY}) if (APPLE) find_package(Threads REQUIRED) diff --git a/solc/CMakeLists.txt b/solc/CMakeLists.txt index cf1e42572..bc8632373 100644 --- a/solc/CMakeLists.txt +++ b/solc/CMakeLists.txt @@ -11,8 +11,8 @@ set(EXECUTABLE solc) file(GLOB HEADERS "*.h") add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) -target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY_RELEASE}) -target_link_libraries(${EXECUTABLE} ${Boost_PROGRAM_OPTIONS_LIBRARY_RELEASE}) +target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${Boost_PROGRAM_OPTIONS_LIBRARY}) target_link_libraries(${EXECUTABLE} solidity) install( TARGETS ${EXECUTABLE} DESTINATION bin ) From 708d5536aec6c678cda52595d3d08a810cd0eb9d Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Mon, 15 Dec 2014 18:42:53 +0100 Subject: [PATCH 201/277] modyfied findjsoncpp cmake to look for debug library --- cmake/FindJsoncpp.cmake | 138 ++++++++++++---------------------------- 1 file changed, 41 insertions(+), 97 deletions(-) diff --git a/cmake/FindJsoncpp.cmake b/cmake/FindJsoncpp.cmake index fe72a9042..c2f0aca43 100644 --- a/cmake/FindJsoncpp.cmake +++ b/cmake/FindJsoncpp.cmake @@ -1,103 +1,47 @@ -# - try to find JSONCPP library +# Find jsoncpp # -# Cache Variables: (probably not for direct use in your scripts) -# JSONCPP_INCLUDE_DIR -# JSONCPP_LIBRARY -# -# Non-cache variables you might use in your CMakeLists.txt: -# JSONCPP_FOUND -# JSONCPP_INCLUDE_DIRS -# JSONCPP_LIBRARIES -# -# Requires these CMake modules: -# FindPackageHandleStandardArgs (known included with CMake >=2.6.2) -# -# Author: -# 2011 Philippe Crassous (ENSAM ParisTech / Institut Image) p.crassous _at_ free.fr -# -# Adapted from the Virtual Reality Peripheral Network library. -# https://github.com/rpavlik/vrpn/blob/master/README.Legal -# - -set(JSONCPP_ROOT_DIR - "${JSONCPP_ROOT_DIR}" - CACHE - PATH - "Directory to search for JSONCPP") -set(_jsoncppnames) -set(_pathsuffixes - suncc - vacpp - mingw - msvc6 - msvc7 - msvc71 - msvc80 - msvc90 - linux-gcc) -if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - execute_process(COMMAND - ${CMAKE_CXX_COMPILER} - -dumpversion - OUTPUT_VARIABLE - _gnucxx_ver - OUTPUT_STRIP_TRAILING_WHITESPACE) - list(APPEND - _jsoncppnames - json_linux-gcc-${_gnucxx_ver}_libmt - json_linux-gcc_libmt) - list(APPEND _pathsuffixes linux-gcc-${_gnucxx_ver}) -elseif(MSVC) - if(MSVC_VERSION EQUAL 1200) - list(APPEND _jsoncppnames json_vc6_libmt) - elseif(MSVC_VERSION EQUAL 1300) - list(APPEND _jsoncppnames json_vc7_libmt) - elseif(MSVC_VERSION EQUAL 1310) - list(APPEND _jsoncppnames json_vc71_libmt) - elseif(MSVC_VERSION EQUAL 1400) - list(APPEND _jsoncppnames json_vc8_libmt) - elseif(MSVC_VERSION EQUAL 1500) - list(APPEND _jsoncppnames json_vc9_libmt) - elseif(MSVC_VERSION EQUAL 1600) - list(APPEND _jsoncppnames json_vc10_libmt) - endif() -else() - list(APPEND _jsoncppnames - json_suncc_libmt - json_vacpp_libmt) -endif() - -list(APPEND _jsoncppnames - json_mingw_libmt - jsoncpp) - -find_library(JSONCPP_LIBRARY - NAMES - ${_jsoncppnames} - PATHS - "${JSONCPP_ROOT_DIR}/libs" - PATH_SUFFIXES - ${_pathsuffixes}) - -find_path(JSONCPP_INCLUDE_DIR - NAMES - json/json.h - PATHS - "${JSONCPP_ROOT_DIR}" - PATH_SUFFIXES jsoncpp - include) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(JSONCPP - DEFAULT_MSG +# Find the jsoncpp includes and library +# +# if you nee to add a custom library search path, do it via via CMAKE_FIND_ROOT_PATH +# +# This module defines +# JSONCPP_INCLUDE_DIRS, where to find header, etc. +# JSONCPP_LIBRARIES, the libraries needed to use jsoncpp. +# JSONCPP_FOUND, If false, do not try to use jsoncpp. + +# only look in default directories +find_path( + JSONCPP_INCLUDE_DIR + NAMES jsoncpp/json/json.h + DOC "jsoncpp include dir" +) + +find_library( JSONCPP_LIBRARY - JSONCPP_INCLUDE_DIR) + NAMES jsoncpp + DOC "jsoncpp library" +) + +set(JSONCPP_INCLUDE_DIRS ${JSONCPP_INCLUDE_DIR}) +set(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY}) + +# debug library on windows +# same naming convention as in qt (appending debug library with d) +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + find_library( + JSONCPP_LIBRARY_DEBUG + NAMES jsoncppd + DOC "jsoncpp debug library" + ) + + set(JSONCPP_LIBRARIES ${JSONCPP_LIBRARIES} ${JSONCPP_LIBRARY_DEBUG}) -if(JSONCPP_FOUND) - set(JSONCPP_LIBRARIES "${JSONCPP_LIBRARY}") - set(JSONCPP_INCLUDE_DIRS "${JSONCPP_INCLUDE_DIR}") - mark_as_advanced(JSONCPP_ROOT_DIR) endif() -mark_as_advanced(JSONCPP_INCLUDE_DIR JSONCPP_LIBRARY) +# handle the QUIETLY and REQUIRED arguments and set GMP_FOUND to TRUE +# if all listed variables are TRUE, hide their existence from configuration view +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(jsoncpp DEFAULT_MSG + JSONCPP_INCLUDE_DIR JSONCPP_LIBRARY) +mark_as_advanced (JSONCPP_INCLUDE_DIR JSONCPP_LIBRARY) From f42dbcac1ccdfeaef7329214f026793d861e807d Mon Sep 17 00:00:00 2001 From: ethdev Date: Mon, 15 Dec 2014 19:01:20 +0100 Subject: [PATCH 202/277] boost library -> libraries --- cmake/EthDependencies.cmake | 4 ---- eth/CMakeLists.txt | 4 ++-- libdevcore/CMakeLists.txt | 8 ++++---- libdevcrypto/CMakeLists.txt | 2 +- libethereum/CMakeLists.txt | 2 +- solc/CMakeLists.txt | 4 ++-- test/CMakeLists.txt | 4 ++-- 7 files changed, 12 insertions(+), 16 deletions(-) diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index 7ff225594..ee93a5311 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -141,10 +141,6 @@ find_package(Boost 1.54.0 REQUIRED COMPONENTS thread date_time system regex chro message(" - boost header: ${Boost_INCLUDE_DIRS}") message(" - boost lib : ${Boost_LIBRARIES}") -message("debug ${Boost_SYSTEM_LIBRARY_DEBUG}") -message("release ${Boost_SYSTEM_LIBRARY_RELEASE}") -message("other ${Boost_SYSTEM_LIBRARY}") - if (APPLE) link_directories(/usr/local/lib) include_directories(/usr/local/include) diff --git a/eth/CMakeLists.txt b/eth/CMakeLists.txt index 739c2991c..27fd542c1 100644 --- a/eth/CMakeLists.txt +++ b/eth/CMakeLists.txt @@ -14,8 +14,8 @@ add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) add_dependencies(${EXECUTABLE} BuildInfo.h) -target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARY_RELEASE}) -target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY_RELEASE}) +target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARIES}) +target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARIES}) if (READLINE_FOUND) target_link_libraries(${EXECUTABLE} ${READLINE_LIBRARIES}) diff --git a/libdevcore/CMakeLists.txt b/libdevcore/CMakeLists.txt index ce8abcbb3..df93361a4 100644 --- a/libdevcore/CMakeLists.txt +++ b/libdevcore/CMakeLists.txt @@ -25,10 +25,10 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) -target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY}) -target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY}) -target_link_libraries(${EXECUTABLE} ${Boost_CHRONO_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARIES}) +target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARIES}) +target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARIES}) +target_link_libraries(${EXECUTABLE} ${Boost_CHRONO_LIBRARIES}) if (APPLE) find_package(Threads REQUIRED) diff --git a/libdevcrypto/CMakeLists.txt b/libdevcrypto/CMakeLists.txt index 20eab916a..4cd6daf21 100644 --- a/libdevcrypto/CMakeLists.txt +++ b/libdevcrypto/CMakeLists.txt @@ -23,7 +23,7 @@ else() add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS}) endif() -target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY_RELEASE}) +target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) target_link_libraries(${EXECUTABLE} devcore) diff --git a/libethereum/CMakeLists.txt b/libethereum/CMakeLists.txt index 792ed0cf1..3906074fd 100644 --- a/libethereum/CMakeLists.txt +++ b/libethereum/CMakeLists.txt @@ -25,7 +25,7 @@ else() endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) -target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARY_RELEASE}) +target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARIES}) target_link_libraries(${EXECUTABLE} evm) target_link_libraries(${EXECUTABLE} lll) diff --git a/solc/CMakeLists.txt b/solc/CMakeLists.txt index bc8632373..8c0ece27e 100644 --- a/solc/CMakeLists.txt +++ b/solc/CMakeLists.txt @@ -11,8 +11,8 @@ set(EXECUTABLE solc) file(GLOB HEADERS "*.h") add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) -target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY}) -target_link_libraries(${EXECUTABLE} ${Boost_PROGRAM_OPTIONS_LIBRARY}) +target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARIES}) +target_link_libraries(${EXECUTABLE} ${Boost_PROGRAM_OPTIONS_LIBRARIES}) target_link_libraries(${EXECUTABLE} solidity) install( TARGETS ${EXECUTABLE} DESTINATION bin ) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7e618f7ea..f862de24c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -12,7 +12,7 @@ file(GLOB HEADERS "*.h") add_executable(testeth ${SRC_LIST} ${HEADERS}) add_executable(createRandomTest createRandomTest.cpp vm.cpp TestHelper.cpp) -target_link_libraries(testeth ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE}) +target_link_libraries(testeth ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) target_link_libraries(testeth ${CURL_LIBRARIES}) target_link_libraries(testeth ethereum) target_link_libraries(testeth ethcore) @@ -25,6 +25,6 @@ if (JSONRPC) target_link_libraries(testeth ${JSON_RPC_CPP_CLIENT_LIBRARIES}) endif() -target_link_libraries(createRandomTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE}) +target_link_libraries(createRandomTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) target_link_libraries(createRandomTest ethereum) target_link_libraries(createRandomTest ethcore) From 10763f2407923578f0560d13c06d017dbd4b0de1 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 15 Dec 2014 19:16:31 +0100 Subject: [PATCH 203/277] - call initKeyEventManager in a SLOT connected to ressourceLoaded SIGNAL --- mix/AppContext.h | 1 + mix/main.cpp | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/mix/AppContext.h b/mix/AppContext.h index 0016ab3be..ce00205d8 100644 --- a/mix/AppContext.h +++ b/mix/AppContext.h @@ -59,6 +59,7 @@ private: public slots: void quitApplication() { delete Instance; } + void resourceLoaded(QObject* _obj, QUrl _url) { Q_UNUSED(_obj); Q_UNUSED(_url); initKeyEventManager(); } }; } diff --git a/mix/main.cpp b/mix/main.cpp index 33a139f85..36a742f8f 100644 --- a/mix/main.cpp +++ b/mix/main.cpp @@ -35,9 +35,7 @@ int main(int _argc, char *_argv[]) QQmlApplicationEngine* engine = new QQmlApplicationEngine(); AppContext::setApplicationContext(engine); QObject::connect(&app, SIGNAL(lastWindowClosed()), AppContext::getInstance(), SLOT(quitApplication())); //use to kill ApplicationContext and other stuff - - engine->load(QUrl(QStringLiteral("qrc:/qml/main.qml"))); - - AppContext::getInstance()->initKeyEventManager(); //has to be called after the loading of the main view. + QObject::connect(engine, SIGNAL(objectCreated(QObject*, QUrl)), AppContext::getInstance(), SLOT(resourceLoaded(QObject*, QUrl))); + engine->load(QUrl("qrc:/qml/main.qml")); return app.exec(); } From 95217d0584cb76a8a50031ff658dd95f56af0c0e Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 15 Dec 2014 19:40:04 +0100 Subject: [PATCH 204/277] - add parameter QObject* in initKeyEventManager. --- mix/AppContext.cpp | 4 ++-- mix/AppContext.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mix/AppContext.cpp b/mix/AppContext.cpp index 5b8b76139..92b3f4c0a 100644 --- a/mix/AppContext.cpp +++ b/mix/AppContext.cpp @@ -52,9 +52,9 @@ dev::eth::Client* AppContext::getEthereumClient() return m_webThree->ethereum(); } -void AppContext::initKeyEventManager() +void AppContext::initKeyEventManager(QObject* _res) { - QObject* mainContent = m_applicationEngine->rootObjects().at(0)->findChild("mainContent", Qt::FindChildrenRecursively); + QObject* mainContent = _res->findChild("mainContent", Qt::FindChildrenRecursively); if (mainContent) QObject::connect(mainContent, SIGNAL(keyPressed(QVariant)), m_keyEventManager.get(), SLOT(keyPressed(QVariant))); else diff --git a/mix/AppContext.h b/mix/AppContext.h index ce00205d8..baa2905ba 100644 --- a/mix/AppContext.h +++ b/mix/AppContext.h @@ -47,7 +47,7 @@ public: static void setApplicationContext(QQmlApplicationEngine* _engine); QQmlApplicationEngine* appEngine(); dev::eth::Client* getEthereumClient(); - void initKeyEventManager(); + void initKeyEventManager(QObject* _obj); KeyEventManager* getKeyEventManager(); void displayMessageDialog(QString _title, QString _message); @@ -59,7 +59,7 @@ private: public slots: void quitApplication() { delete Instance; } - void resourceLoaded(QObject* _obj, QUrl _url) { Q_UNUSED(_obj); Q_UNUSED(_url); initKeyEventManager(); } + void resourceLoaded(QObject* _obj, QUrl _url) { Q_UNUSED(_url); initKeyEventManager(_obj); } }; } From 905934f4c8e67d796d6d8a97a74d8003c9feeed5 Mon Sep 17 00:00:00 2001 From: winsvega Date: Mon, 15 Dec 2014 23:50:43 +0300 Subject: [PATCH 205/277] Transaction Test Filler --- test/stTransactionTestFiller.json | 191 ++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 test/stTransactionTestFiller.json diff --git a/test/stTransactionTestFiller.json b/test/stTransactionTestFiller.json new file mode 100644 index 000000000..260e7953f --- /dev/null +++ b/test/stTransactionTestFiller.json @@ -0,0 +1,191 @@ +{ + "EmptyTransaction" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "100000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "", + "gasLimit" : "", + "gasPrice" : "", + "nonce" : "", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "", + "value" : "" + } + }, + + "TransactionSendingToEmpty" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "100000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "", + "gasLimit" : "500", + "gasPrice" : "1", + "nonce" : "", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "", + "value" : "" + } + }, + + + "TransactionSendingToZero" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "100000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "", + "gasLimit" : "5000", + "gasPrice" : "1", + "nonce" : "", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "0000000000000000000000000000000000000000", + "value" : "1" + } + }, + + + "TransactionToItself" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "100000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "", + "gasLimit" : "5000", + "gasPrice" : "1", + "nonce" : "", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "1" + } + }, + + + "TransactionToItselfNotEnoughFounds" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1101", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "", + "gasLimit" : "600", + "gasPrice" : "1", + "nonce" : "", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "502" + } + }, + + + "TransactionFromCoinbaseNotEnoughFounds" : { + "env" : { + "currentCoinbase" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1100", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "b94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000", + "code" : "", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "", + "gasLimit" : "600", + "gasPrice" : "1", + "nonce" : "", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "502" + } + } +} From 93d70bf9573087e5e27017188e3a306f518e2e6d Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 16 Dec 2014 12:25:14 +0100 Subject: [PATCH 206/277] search for leveldb debug library --- cmake/FindLevelDB.cmake | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/cmake/FindLevelDB.cmake b/cmake/FindLevelDB.cmake index 6bd373a9f..b2f59ec4d 100644 --- a/cmake/FindLevelDB.cmake +++ b/cmake/FindLevelDB.cmake @@ -25,6 +25,19 @@ find_library( set(LEVELDB_INCLUDE_DIRS ${LEVELDB_INCLUDE_DIR}) set(LEVELDB_LIBRARIES ${LEVELDB_LIBRARY}) +# debug library on windows +# same naming convention as in qt (appending debug library with d) +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + find_library( + LEVELDB_LIBRARY_DEBUG + NAMES leveldbd + DOC "leveldb debug library" + ) + + set(LEVELDB_LIBRARIES ${LEVELDB_LIBRARIES} ${LEVELDB_LIBRARY_DEBUG}) + +endif() + # handle the QUIETLY and REQUIRED arguments and set LEVELDB_FOUND to TRUE # if all listed variables are TRUE, hide their existence from configuration view include(FindPackageHandleStandardArgs) From a68cb3f0b8294e44c4c72e219ac61814b1843b81 Mon Sep 17 00:00:00 2001 From: ethdev Date: Tue, 16 Dec 2014 12:45:03 +0100 Subject: [PATCH 207/277] jsoncpp && leveldb are now using optimized/debug --- alethzero/CMakeLists.txt | 1 - cmake/FindJsoncpp.cmake | 3 ++- cmake/FindLevelDB.cmake | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index c4237eaee..39c02d6be 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -32,7 +32,6 @@ eth_add_executable(${EXECUTABLE} add_dependencies(${EXECUTABLE} BuildInfo.h) target_link_libraries(${EXECUTABLE} Qt5::Core) -target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES}) target_link_libraries(${EXECUTABLE} webthree) target_link_libraries(${EXECUTABLE} qethereum) target_link_libraries(${EXECUTABLE} ethereum) diff --git a/cmake/FindJsoncpp.cmake b/cmake/FindJsoncpp.cmake index c2f0aca43..392b57ffb 100644 --- a/cmake/FindJsoncpp.cmake +++ b/cmake/FindJsoncpp.cmake @@ -27,6 +27,7 @@ set(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY}) # debug library on windows # same naming convention as in qt (appending debug library with d) +# boost is using the same "hack" as us with "optimized" and "debug" if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") find_library( JSONCPP_LIBRARY_DEBUG @@ -34,7 +35,7 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") DOC "jsoncpp debug library" ) - set(JSONCPP_LIBRARIES ${JSONCPP_LIBRARIES} ${JSONCPP_LIBRARY_DEBUG}) + set(JSONCPP_LIBRARIES optimized ${JSONCPP_LIBRARIES} debug ${JSONCPP_LIBRARY_DEBUG}) endif() diff --git a/cmake/FindLevelDB.cmake b/cmake/FindLevelDB.cmake index b2f59ec4d..a4aef1705 100644 --- a/cmake/FindLevelDB.cmake +++ b/cmake/FindLevelDB.cmake @@ -27,6 +27,7 @@ set(LEVELDB_LIBRARIES ${LEVELDB_LIBRARY}) # debug library on windows # same naming convention as in qt (appending debug library with d) +# boost is using the same "hack" as us with "optimized" and "debug" if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") find_library( LEVELDB_LIBRARY_DEBUG @@ -34,7 +35,7 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") DOC "leveldb debug library" ) - set(LEVELDB_LIBRARIES ${LEVELDB_LIBRARIES} ${LEVELDB_LIBRARY_DEBUG}) + set(LEVELDB_LIBRARIES optimized ${LEVELDB_LIBRARIES} debug ${LEVELDB_LIBRARY_DEBUG}) endif() From b2bcf713a60781cdce8a9db19a054d6abd5e0a19 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 16 Dec 2014 13:17:30 +0100 Subject: [PATCH 208/277] - Replace Qt5.3 ModalDialog by custom modal dialog. --- mix/AppContext.cpp | 9 ++++----- mix/Extension.cpp | 5 ++--- mix/qml.qrc | 2 ++ mix/qml/AlertMessageDialog.qml | 27 +++++++++++++++++++++++++++ mix/qml/BasicMessage.qml | 1 + mix/qml/Debugger.qml | 8 -------- mix/qml/ModalDialog.qml | 27 +++++++++++++++++++++++++++ mix/qml/main.qml | 22 +++------------------- 8 files changed, 66 insertions(+), 35 deletions(-) create mode 100644 mix/qml/AlertMessageDialog.qml create mode 100644 mix/qml/ModalDialog.qml diff --git a/mix/AppContext.cpp b/mix/AppContext.cpp index 92b3f4c0a..89f2849cd 100644 --- a/mix/AppContext.cpp +++ b/mix/AppContext.cpp @@ -74,14 +74,13 @@ void AppContext::setApplicationContext(QQmlApplicationEngine* _engine) void AppContext::displayMessageDialog(QString _title, QString _message) { - QQmlComponent component(m_applicationEngine.get(), QUrl("qrc:/qml/BasicMessage.qml")); - QObject* dialog = component.create(); - dialog->findChild("messageContent", Qt::FindChildrenRecursively)->setProperty("text", _message); - QObject* dialogWin = AppContext::getInstance()->appEngine()->rootObjects().at(0)->findChild("messageDialog", Qt::FindChildrenRecursively); + QObject* dialogWin = m_applicationEngine.get()->rootObjects().at(0)->findChild("alertMessageDialog", Qt::FindChildrenRecursively); + QObject* dialogWinComponent = m_applicationEngine.get()->rootObjects().at(0)->findChild("alertMessageDialogContent", Qt::FindChildrenRecursively); QMetaObject::invokeMethod(dialogWin, "close"); - dialogWin->setProperty("contentItem", QVariant::fromValue(dialog)); + dialogWinComponent->setProperty("source", QString("qrc:/qml/BasicMessage.qml")); dialogWin->setProperty("title", _title); dialogWin->setProperty("width", "250"); dialogWin->setProperty("height", "100"); + dialogWin->findChild("messageContent", Qt::FindChildrenRecursively)->setProperty("text", _message); QMetaObject::invokeMethod(dialogWin, "open"); } diff --git a/mix/Extension.cpp b/mix/Extension.cpp index f9a8ad94d..e46fc4145 100644 --- a/mix/Extension.cpp +++ b/mix/Extension.cpp @@ -65,11 +65,10 @@ void Extension::addContentOn(QObject* _view) Q_UNUSED(_view); if (m_displayBehavior == ExtensionDisplayBehavior::ModalDialog) { - QQmlComponent component(AppContext::getInstance()->appEngine(), QUrl(contentUrl())); - QObject* dialog = component.create(); QObject* dialogWin = AppContext::getInstance()->appEngine()->rootObjects().at(0)->findChild("dialog", Qt::FindChildrenRecursively); + QObject* dialogWinComponent = AppContext::getInstance()->appEngine()->rootObjects().at(0)->findChild("modalDialogContent", Qt::FindChildrenRecursively); QMetaObject::invokeMethod(dialogWin, "close"); - dialogWin->setProperty("contentItem", QVariant::fromValue(dialog)); + dialogWinComponent->setProperty("source", contentUrl()); dialogWin->setProperty("title", title()); QMetaObject::invokeMethod(dialogWin, "open"); } diff --git a/mix/qml.qrc b/mix/qml.qrc index 2fa92d661..d14aa9974 100644 --- a/mix/qml.qrc +++ b/mix/qml.qrc @@ -7,5 +7,7 @@ qml/Debugger.qml qml/js/Debugger.js qml/BasicMessage.qml + qml/ModalDialog.qml + qml/AlertMessageDialog.qml diff --git a/mix/qml/AlertMessageDialog.qml b/mix/qml/AlertMessageDialog.qml new file mode 100644 index 000000000..f89ade45f --- /dev/null +++ b/mix/qml/AlertMessageDialog.qml @@ -0,0 +1,27 @@ +import QtQuick 2.2 +import QtQuick.Window 2.0 + +Window +{ + id: alertMessageDialog + title: "" + modality: Qt.WindowModal + height: 150 + width: 200 + visible: false + Loader + { + focus: true + id: alertMessageDialogContent + objectName: "alertMessageDialogContent" + anchors.fill: parent + } + function open() + { + visible = true + } + function close() + { + visible = false + } +} diff --git a/mix/qml/BasicMessage.qml b/mix/qml/BasicMessage.qml index 0678c9b54..233717009 100644 --- a/mix/qml/BasicMessage.qml +++ b/mix/qml/BasicMessage.qml @@ -18,3 +18,4 @@ Rectangle { text: "" } } + diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml index e895d1ada..fa3e8aba4 100644 --- a/mix/qml/Debugger.qml +++ b/mix/qml/Debugger.qml @@ -21,7 +21,6 @@ Rectangle { font.italic: true id: headerInfoLabel } - } Keys.onPressed: { @@ -138,7 +137,6 @@ Rectangle { horizontalAlignment: "AlignHCenter" font.family: "Verdana" font.pointSize: 8 - font.letterSpacing: 2 width: parent.width height: 15 anchors.top : parent.top @@ -149,7 +147,6 @@ Rectangle { width: parent.width font.family: "Verdana" font.pointSize: 8 - font.letterSpacing: 2 height: parent.height - 15 id:debugStackTxt readOnly: true; @@ -166,7 +163,6 @@ Rectangle { horizontalAlignment: "AlignHCenter" font.family: "Verdana" font.pointSize: 8 - font.letterSpacing: 2 width: parent.width height: 15 anchors.top : parent.top @@ -177,7 +173,6 @@ Rectangle { width: parent.width font.family: "Verdana" font.pointSize: 8 - font.letterSpacing: 2 height: parent.height - 15 id: debugMemoryTxt readOnly: true; @@ -194,7 +189,6 @@ Rectangle { horizontalAlignment: "AlignHCenter" font.family: "Verdana" font.pointSize: 8 - font.letterSpacing: 2 width: parent.width height: 15 anchors.top : parent.top @@ -205,7 +199,6 @@ Rectangle { width: parent.width font.family: "Verdana" font.pointSize: 8 - font.letterSpacing: 2 height: parent.height - 15 id:debugStorageTxt readOnly: true; @@ -222,7 +215,6 @@ Rectangle { horizontalAlignment: "AlignHCenter" font.family: "Verdana" font.pointSize: 8 - font.letterSpacing: 2 width: parent.width height: 15 anchors.top : parent.top diff --git a/mix/qml/ModalDialog.qml b/mix/qml/ModalDialog.qml new file mode 100644 index 000000000..983420926 --- /dev/null +++ b/mix/qml/ModalDialog.qml @@ -0,0 +1,27 @@ +import QtQuick 2.2 +import QtQuick.Window 2.0 + +Window +{ + id: modalDialog + title: "" + modality: Qt.WindowModal + height: 400 + width: 700 + visible: false + Loader + { + focus: true + id: modalDialogContent + objectName: "modalDialogContent" + anchors.fill: parent + } + function open() + { + visible = true + } + function close() + { + visible = false + } +} diff --git a/mix/qml/main.qml b/mix/qml/main.qml index 05b29eb62..52c47e063 100644 --- a/mix/qml/main.qml +++ b/mix/qml/main.qml @@ -30,29 +30,13 @@ ApplicationWindow { MainContent { } - Dialog { - x: mainApplication.x + (mainApplication.width - width) / 2 - y: mainApplication.y + (mainApplication.height - height) / 2 + ModalDialog { objectName: "dialog" id: dialog - height: 400 - width: 700 - modality: Qt.WindowModal - contentItem: Rectangle { - objectName: "dialogContent" - } } - Dialog { - x: mainApplication.x + (mainApplication.width - width) / 2 - y: mainApplication.y + (mainApplication.height - height) / 2 - objectName: "messageDialog" + AlertMessageDialog { + objectName: "alertMessageDialog" id: messageDialog - height: 150 - width: 200 - modality: Qt.WindowModal - contentItem: Rectangle { - objectName: "messageContent" - } } } From e2223b8057e40a3af5a79c2df7f48a7674bc2cb5 Mon Sep 17 00:00:00 2001 From: ethdev Date: Tue, 16 Dec 2014 15:31:34 +0100 Subject: [PATCH 209/277] missing boost include in eth --- eth/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/eth/CMakeLists.txt b/eth/CMakeLists.txt index 27fd542c1..c98f3cbec 100644 --- a/eth/CMakeLists.txt +++ b/eth/CMakeLists.txt @@ -3,6 +3,7 @@ set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) +include_directories(${Boost_INCLUDE_DIRS}) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) include_directories(..) From 0532223f516a8853bfd90e38bcdd51d2fa27e39b Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 16 Dec 2014 16:03:23 +0100 Subject: [PATCH 210/277] fixed typo --- cmake/FindGmp.cmake | 2 +- cmake/FindJsonRpcCpp.cmake | 2 +- cmake/FindJsoncpp.cmake | 4 ++-- cmake/FindLevelDB.cmake | 2 +- cmake/FindMiniupnpc.cmake | 2 +- cmake/FindReadline.cmake | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cmake/FindGmp.cmake b/cmake/FindGmp.cmake index 4dc8f48c4..1cffa7efa 100644 --- a/cmake/FindGmp.cmake +++ b/cmake/FindGmp.cmake @@ -2,7 +2,7 @@ # # Find the gmp includes and library # -# if you nee to add a custom library search path, do it via via CMAKE_FIND_ROOT_PATH +# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH # # This module defines # GMP_INCLUDE_DIRS, where to find header, etc. diff --git a/cmake/FindJsonRpcCpp.cmake b/cmake/FindJsonRpcCpp.cmake index eecf518f8..3072ff244 100644 --- a/cmake/FindJsonRpcCpp.cmake +++ b/cmake/FindJsonRpcCpp.cmake @@ -2,7 +2,7 @@ # # Find the json-rpc-cpp includes and library # -# if you nee to add a custom library search path, do it via via CMAKE_FIND_ROOT_PATH +# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH # # This module defines # JSON_RCP_CPP_INCLUDE_DIRS, where to find header, etc. diff --git a/cmake/FindJsoncpp.cmake b/cmake/FindJsoncpp.cmake index 392b57ffb..36ba12a3e 100644 --- a/cmake/FindJsoncpp.cmake +++ b/cmake/FindJsoncpp.cmake @@ -2,7 +2,7 @@ # # Find the jsoncpp includes and library # -# if you nee to add a custom library search path, do it via via CMAKE_FIND_ROOT_PATH +# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH # # This module defines # JSONCPP_INCLUDE_DIRS, where to find header, etc. @@ -39,7 +39,7 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") endif() -# handle the QUIETLY and REQUIRED arguments and set GMP_FOUND to TRUE +# handle the QUIETLY and REQUIRED arguments and set JSONCPP_FOUND to TRUE # if all listed variables are TRUE, hide their existence from configuration view include(FindPackageHandleStandardArgs) find_package_handle_standard_args(jsoncpp DEFAULT_MSG diff --git a/cmake/FindLevelDB.cmake b/cmake/FindLevelDB.cmake index a4aef1705..b1a9a5815 100644 --- a/cmake/FindLevelDB.cmake +++ b/cmake/FindLevelDB.cmake @@ -2,7 +2,7 @@ # # Find the leveldb includes and library # -# if you nee to add a custom library search path, do it via via CMAKE_FIND_ROOT_PATH +# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH # # This module defines # LEVELDB_INCLUDE_DIRS, where to find header, etc. diff --git a/cmake/FindMiniupnpc.cmake b/cmake/FindMiniupnpc.cmake index 4ecbb0c4a..1438a8526 100644 --- a/cmake/FindMiniupnpc.cmake +++ b/cmake/FindMiniupnpc.cmake @@ -2,7 +2,7 @@ # # Find the miniupnpc includes and library # -# if you nee to add a custom library search path, do it via via CMAKE_FIND_ROOT_PATH +# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH # # This module defines # MINIUPNPC_INCLUDE_DIRS, where to find header, etc. diff --git a/cmake/FindReadline.cmake b/cmake/FindReadline.cmake index 1f47db4a7..c1cdfd33a 100644 --- a/cmake/FindReadline.cmake +++ b/cmake/FindReadline.cmake @@ -2,7 +2,7 @@ # # Find the readline includes and library # -# if you nee to add a custom library search path, do it via via CMAKE_FIND_ROOT_PATH +# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH # # This module defines # READLINE_INCLUDE_DIRS, where to find header, etc. From a22376093a54bc7f478e9458ca4f350cd623c846 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 16 Dec 2014 16:14:13 +0100 Subject: [PATCH 211/277] Prepared State premine. Fixes for Qt 5.2. --- mix/AssemblyDebuggerCtrl.cpp | 3 +-- mix/AssemblyDebuggerModel.cpp | 39 +++++++++++++++++++++-------------- mix/AssemblyDebuggerModel.h | 21 ++++++++++++------- mix/qml/BasicMessage.qml | 6 +++--- mix/qml/Debugger.qml | 6 +++--- mix/qml/MainContent.qml | 4 ++-- mix/qml/main.qml | 2 +- 7 files changed, 48 insertions(+), 33 deletions(-) diff --git a/mix/AssemblyDebuggerCtrl.cpp b/mix/AssemblyDebuggerCtrl.cpp index 678f94d77..e955dfd23 100644 --- a/mix/AssemblyDebuggerCtrl.cpp +++ b/mix/AssemblyDebuggerCtrl.cpp @@ -69,11 +69,10 @@ void AssemblyDebuggerCtrl::keyPressed(int _key) return; } - KeyPair ad = KeyPair::create(); u256 gasPrice = 10000000000000; u256 gas = 1000000; u256 amount = 100; - DebuggingContent debuggingContent = m_modelDebugger->getContractInitiationDebugStates(amount, gasPrice, gas, m_doc->toPlainText(), ad); + DebuggingContent debuggingContent = m_modelDebugger->getContractInitiationDebugStates(amount, gasPrice, gas, m_doc->toPlainText()); //we need to wrap states in a QObject before sending to QML. QList wStates; diff --git a/mix/AssemblyDebuggerModel.cpp b/mix/AssemblyDebuggerModel.cpp index 151c14773..1e07760e1 100644 --- a/mix/AssemblyDebuggerModel.cpp +++ b/mix/AssemblyDebuggerModel.cpp @@ -18,30 +18,36 @@ */ #include -#include "libethereum/Executive.h" -#include "libethereum/Transaction.h" -#include "libethereum/ExtVM.h" -#include "libevm/VM.h" -#include "libdevcore/Common.h" +#include +#include +#include +#include +#include #include "AppContext.h" #include "TransactionBuilder.h" #include "AssemblyDebuggerModel.h" #include "ConstantCompilationModel.h" #include "DebuggingStateWrapper.h" +using namespace std; using namespace dev; using namespace dev::eth; using namespace dev::mix; -AssemblyDebuggerModel::AssemblyDebuggerModel() +AssemblyDebuggerModel::AssemblyDebuggerModel(): + m_userAccount(KeyPair::create()), + m_baseState(Address(), m_overlayDB, BaseState::Empty) { + m_baseState.addBalance(m_userAccount.address(), 10000000 * ether); m_currentExecution = std::unique_ptr(new Executive(m_executiveState, 0)); } DebuggingContent AssemblyDebuggerModel::getContractInitiationDebugStates(dev::bytesConstRef _rawTransaction) { + // Reset the state back to our clean premine. + m_executiveState = m_baseState; + QList states; - Transaction tr(_rawTransaction); - m_currentExecution->create(tr.sender(), tr.value(), tr.gasPrice(), tr.gas(), &tr.data(), tr.sender()); + m_currentExecution->setup(_rawTransaction); std::vector levels; bytes code; bytesConstRef data; @@ -67,7 +73,9 @@ DebuggingContent AssemblyDebuggerModel::getContractInitiationDebugStates(dev::by vm.stack(), vm.memory(), gasCost, ext.state().storage(ext.myAddress), levels})); }; + m_currentExecution->go(onOp); + cdebug << states.size(); m_currentExecution->finalize(onOp); DebuggingContent d; @@ -79,11 +87,12 @@ DebuggingContent AssemblyDebuggerModel::getContractInitiationDebugStates(dev::by return d; } -DebuggingContent AssemblyDebuggerModel::getContractInitiationDebugStates(dev::u256 _value, - dev::u256 _gasPrice, - dev::u256 _gas, - QString _code, - KeyPair _key) +DebuggingContent AssemblyDebuggerModel::getContractInitiationDebugStates( + dev::u256 _value, + dev::u256 _gasPrice, + dev::u256 _gas, + QString _code +) { ConstantCompilationModel compiler; CompilerResult res = compiler.compile(_code); @@ -96,8 +105,8 @@ DebuggingContent AssemblyDebuggerModel::getContractInitiationDebugStates(dev::u2 } TransactionBuilder trBuild; - Transaction tr = trBuild.getCreationTransaction(_value, _gasPrice, _gas, res.bytes, - m_executiveState.transactionsFrom(dev::toAddress(_key.secret())), _key.secret()); + Transaction tr = trBuild.getCreationTransaction(_value, _gasPrice, min(_gas, m_baseState.gasLimitRemaining()), res.bytes, + m_executiveState.transactionsFrom(dev::toAddress(m_userAccount.secret())), m_userAccount.secret()); bytes b = tr.rlp(); dev::bytesConstRef bytesRef = &b; return getContractInitiationDebugStates(bytesRef); diff --git a/mix/AssemblyDebuggerModel.h b/mix/AssemblyDebuggerModel.h index 3ed6818bc..b6e0224e8 100644 --- a/mix/AssemblyDebuggerModel.h +++ b/mix/AssemblyDebuggerModel.h @@ -21,9 +21,10 @@ #include #include -#include "libethereum/State.h" -#include "libethereum/Executive.h" -#include "libdevcore/Common.h" +#include +#include +#include +#include #include "DebuggingStateWrapper.h" namespace dev @@ -31,17 +32,23 @@ namespace dev namespace mix { +/** + * @brief Long-life object for managing all executions. + */ class AssemblyDebuggerModel { public: AssemblyDebuggerModel(); - DebuggingContent getContractInitiationDebugStates(dev::u256, dev::u256, dev::u256, QString, KeyPair); - DebuggingContent getContractInitiationDebugStates(dev::bytesConstRef); + DebuggingContent getContractInitiationDebugStates(u256, u256, u256, QString); + DebuggingContent getContractInitiationDebugStates(bytesConstRef); bool compile(QString); private: - std::unique_ptr m_currentExecution; - dev::eth::State m_executiveState; + KeyPair m_userAccount; + OverlayDB m_overlayDB; + eth::State m_baseState; + eth::State m_executiveState; + std::unique_ptr m_currentExecution; }; } diff --git a/mix/qml/BasicMessage.qml b/mix/qml/BasicMessage.qml index 233717009..7127d29ff 100644 --- a/mix/qml/BasicMessage.qml +++ b/mix/qml/BasicMessage.qml @@ -1,7 +1,7 @@ import QtQuick 2.2 -import QtQuick.Controls.Styles 1.2 -import QtQuick.Controls 1.2 -import QtQuick.Dialogs 1.2 +import QtQuick.Controls.Styles 1.1 +import QtQuick.Controls 1.1 +import QtQuick.Dialogs 1.1 import QtQuick.Layouts 1.1 Rectangle { diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml index fa3e8aba4..18f706970 100644 --- a/mix/qml/Debugger.qml +++ b/mix/qml/Debugger.qml @@ -1,7 +1,7 @@ import QtQuick 2.2 -import QtQuick.Controls.Styles 1.2 -import QtQuick.Controls 1.2 -import QtQuick.Dialogs 1.2 +import QtQuick.Controls.Styles 1.1 +import QtQuick.Controls 1.1 +import QtQuick.Dialogs 1.1 import QtQuick.Layouts 1.1 import "js/Debugger.js" as Debugger diff --git a/mix/qml/MainContent.qml b/mix/qml/MainContent.qml index 1da48a1c8..6d08f79ec 100644 --- a/mix/qml/MainContent.qml +++ b/mix/qml/MainContent.qml @@ -1,7 +1,7 @@ import QtQuick 2.2 -import QtQuick.Controls 1.2 +import QtQuick.Controls 1.1 import QtQuick.Layouts 1.0 -import QtQuick.Controls.Styles 1.2 +import QtQuick.Controls.Styles 1.1 import CodeEditorExtensionManager 1.0 Rectangle { diff --git a/mix/qml/main.qml b/mix/qml/main.qml index 52c47e063..42ee3ef97 100644 --- a/mix/qml/main.qml +++ b/mix/qml/main.qml @@ -1,7 +1,7 @@ import QtQuick 2.2 import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.1 -import QtQuick.Dialogs 1.2 +import QtQuick.Dialogs 1.1 import QtQuick.Layouts 1.1 import QtQuick.Window 2.0 import CodeEditorExtensionManager 1.0 From c00153e5c145cc7ac780195357a7ed6be9e9763a Mon Sep 17 00:00:00 2001 From: Christian Date: Tue, 16 Dec 2014 16:15:34 +0100 Subject: [PATCH 212/277] Stylistic changes. --- libevmcore/Assembly.cpp | 8 +++++++- libsolidity/AST.h | 2 +- libsolidity/Types.cpp | 6 +++--- libsolidity/grammar.txt | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/libevmcore/Assembly.cpp b/libevmcore/Assembly.cpp index b78f03035..74bd015a6 100644 --- a/libevmcore/Assembly.cpp +++ b/libevmcore/Assembly.cpp @@ -60,7 +60,13 @@ int AssemblyItem::deposit() const { case Operation: return instructionInfo((Instruction)(byte)m_data).ret - instructionInfo((Instruction)(byte)m_data).args; - case Push: case PushString: case PushTag: case PushData: case PushSub: case PushSubSize: case PushProgramSize: + case Push: + case PushString: + case PushTag: + case PushData: + case PushSub: + case PushSubSize: + case PushProgramSize: return 1; case Tag: return 0; diff --git a/libsolidity/AST.h b/libsolidity/AST.h index 72f96394f..4bb623b49 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -763,7 +763,7 @@ public: std::vector> getArguments() const { return {m_arguments.begin(), m_arguments.end()}; } /// Returns the referenced contract. Can only be called after type checking. - ContractDefinition const* getContract() const { return m_contract; } + ContractDefinition const* getContract() const { if (asserts(m_contract)) BOOST_THROW_EXCEPTION(InternalCompilerError()); else return m_contract; } private: ASTPointer m_contractName; diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index f1cd7c228..eba11cb0d 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -314,9 +314,9 @@ shared_ptr const& ContractType::getConstructorType() const { if (!m_constructorType) { - FunctionDefinition const* constr = m_contract.getConstructor(); - if (constr) - m_constructorType = make_shared(*constr); + FunctionDefinition const* constructor = m_contract.getConstructor(); + if (constructor) + m_constructorType = make_shared(*constructor); else m_constructorType = make_shared(TypePointers(), TypePointers()); } diff --git a/libsolidity/grammar.txt b/libsolidity/grammar.txt index 793e91882..a26f717a1 100644 --- a/libsolidity/grammar.txt +++ b/libsolidity/grammar.txt @@ -29,7 +29,7 @@ Expression = Assignment | UnaryOperation | BinaryOperation | FunctionCall | NewE MemberAccess | PrimaryExpression // The expression syntax is actually much more complicated Assignment = Expression (AssignmentOp Expression) -FunctionCall = Expression '(' ( Expression ( ',' Expression )* ) ')' +FunctionCall = Expression '(' Expression ( ',' Expression )* ')' NewExpression = 'new' Identifier '(' ( Expression ( ',' Expression )* ) ')' MemberAccess = Expression '.' Identifier IndexAccess = Expression '[' Expresison ']' From 76db957b529f5d436ba2d53787def77769f7729f Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 16 Dec 2014 18:00:39 +0100 Subject: [PATCH 213/277] fixed macdeployqt options order --- cmake/EthExecutableHelper.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmake/EthExecutableHelper.cmake b/cmake/EthExecutableHelper.cmake index 56aa3f6c3..9d273522e 100644 --- a/cmake/EthExecutableHelper.cmake +++ b/cmake/EthExecutableHelper.cmake @@ -61,12 +61,13 @@ macro(eth_install_executable EXECUTABLE) if (ETH_INSTALL_EXECUTABLE_QMLDIR) set(eth_qml_dir "-qmldir=${ETH_INSTALL_EXECUTABLE_QMLDIR}") + message(STATUS "${EXECUTABLE} qmldir: ${eth_qml_dir}") endif() if (APPLE) # First have qt5 install plugins and frameworks add_custom_command(TARGET ${EXECUTABLE} POST_BUILD - COMMAND ${MACDEPLOYQT_APP} ${eth_qml_dir} ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app + COMMAND ${MACDEPLOYQT_APP} ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app ${eth_qml_dir} WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) # This tool and next will inspect linked libraries in order to determine which dependencies are required From 381c30ecd0cba487e523551dd1e7737847cb9f5f Mon Sep 17 00:00:00 2001 From: wanderer Date: Fri, 12 Dec 2014 09:35:18 -0500 Subject: [PATCH 214/277] changed output stacktrace format to json --- test/vm.cpp | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/test/vm.cpp b/test/vm.cpp index 49d6ed104..27e1da238 100644 --- a/test/vm.cpp +++ b/test/vm.cpp @@ -262,12 +262,45 @@ eth::OnOpFunc FakeExtVM::simpleTrace() dev::LogOutputStream(true) << o.str(); dev::LogOutputStream(false) << " | " << std::dec << ext.depth << " | " << ext.myAddress << " | #" << steps << " | " << std::hex << std::setw(4) << std::setfill('0') << vm.curPC() << " : " << instructionInfo(inst).name << " | " << std::dec << vm.gas() << " | -" << std::dec << gasCost << " | " << newMemSize << "x32" << " ]"; + /*creates json stack trace*/ if (eth::VMTraceChannel::verbosity <= g_logVerbosity) { + std::ostringstream ofile; + + u256s stack = vm.stack(); + ofile << endl << "{" << endl << " \"stack\":[" << endl; + for (vector::iterator i = stack.begin(); i != stack.end(); ++i){ + ofile << " \"" << (h256)*i << "\""; + if(next(i) != stack.end()){ + ofile << ","; + } + + ofile << endl; + } + + ofile << " ]," << endl; + ofile << " \"memory\": \""; + for(auto i: vm.memory()) + ofile << setfill('0') << setw(2) << hex << (unsigned)i; + ofile << "\"," << endl; + + ofile << " \"storage\": [" << endl; + for (auto const& i: std::get<2>(ext.addresses.find(ext.myAddress)->second)){ + ofile << " [" << endl; + ofile << " \"" << std::showbase << std::hex << i.first << "\": \"" << i.second << "\"" << std::endl; + } + + ofile << " ]," << endl; + ofile << " \"depth\": " << dec << ext.depth << "," << endl; + ofile << " \"gas\":" << dec < Date: Sun, 14 Dec 2014 13:11:54 -0500 Subject: [PATCH 215/277] using json_spirit --- test/vm.cpp | 77 ++++++++++++++++++++++++++++++++--------------------- test/vm.h | 2 +- 2 files changed, 47 insertions(+), 32 deletions(-) diff --git a/test/vm.cpp b/test/vm.cpp index 27e1da238..39ffdb7b2 100644 --- a/test/vm.cpp +++ b/test/vm.cpp @@ -265,42 +265,57 @@ eth::OnOpFunc FakeExtVM::simpleTrace() /*creates json stack trace*/ if (eth::VMTraceChannel::verbosity <= g_logVerbosity) { - std::ostringstream ofile; - - u256s stack = vm.stack(); - ofile << endl << "{" << endl << " \"stack\":[" << endl; - for (vector::iterator i = stack.begin(); i != stack.end(); ++i){ - ofile << " \"" << (h256)*i << "\""; - if(next(i) != stack.end()){ - ofile << ","; - } + Object o_step; - ofile << endl; - } + /*add the stack*/ + Array a_stack; + for (auto i: vm.stack()) + a_stack.push_back((string)i); - ofile << " ]," << endl; - ofile << " \"memory\": \""; - for(auto i: vm.memory()) - ofile << setfill('0') << setw(2) << hex << (unsigned)i; - ofile << "\"," << endl; + o_step.push_back(Pair( "stack", a_stack )); - ofile << " \"storage\": [" << endl; - for (auto const& i: std::get<2>(ext.addresses.find(ext.myAddress)->second)){ - ofile << " [" << endl; - ofile << " \"" << std::showbase << std::hex << i.first << "\": \"" << i.second << "\"" << std::endl; + /*add the memory*/ + Array a_mem; + for(auto i: vm.memory()) + a_mem.push_back(i); + + o_step.push_back(Pair("memory", a_mem)); + + /*add the storage*/ + Object storage; + for (auto const& i: std::get<2>(ext.addresses.find(ext.myAddress)->second)) + storage.push_back(Pair( (string)i.first , (string)i.second)); + + /*add all the other details*/ + o_step.push_back(Pair("storage", storage)); + o_step.push_back(Pair("depth", to_string(ext.depth))); + o_step.push_back(Pair("gas", (string)vm.gas())); + o_step.push_back(Pair("address", "0x" + toString(ext.myAddress ))); + o_step.push_back(Pair("step", steps )); + o_step.push_back(Pair("pc", (int)vm.curPC())); + o_step.push_back(Pair("opcode", instructionInfo(inst).name )); + + ifstream is( "./stackTrace.json"); + string istr((std::istreambuf_iterator(is) ), (std::istreambuf_iterator())); + is.close(); + Value iv; + Array a_trace; + + /*try to parse the current trace file*/ + try{ + read_string(istr, iv); + a_trace = iv.get_array(); } + catch(...){} + + /*add this step to the array of steps*/ + a_trace.push_back(o_step); + + ofstream os( "./stackTrace.json"); - ofile << " ]," << endl; - ofile << " \"depth\": " << dec << ext.depth << "," << endl; - ofile << " \"gas\":" << dec <. #include #include #include -#include "JsonSpiritHeaders.h" +#include #include #include #include From 4dd5240111dde6368df728fa752f9ae2d7efe53b Mon Sep 17 00:00:00 2001 From: wanderer Date: Tue, 16 Dec 2014 14:28:03 -0500 Subject: [PATCH 216/277] append JSON objects to log --- test/vm.cpp | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/test/vm.cpp b/test/vm.cpp index 39ffdb7b2..010eb4d75 100644 --- a/test/vm.cpp +++ b/test/vm.cpp @@ -295,26 +295,10 @@ eth::OnOpFunc FakeExtVM::simpleTrace() o_step.push_back(Pair("pc", (int)vm.curPC())); o_step.push_back(Pair("opcode", instructionInfo(inst).name )); - ifstream is( "./stackTrace.json"); - string istr((std::istreambuf_iterator(is) ), (std::istreambuf_iterator())); - is.close(); - Value iv; - Array a_trace; - - /*try to parse the current trace file*/ - try{ - read_string(istr, iv); - a_trace = iv.get_array(); - } - catch(...){} - - /*add this step to the array of steps*/ - a_trace.push_back(o_step); - - ofstream os( "./stackTrace.json"); - - Value v(a_trace); - os << write_string(v, true); + /*append the JSON object to the log file*/ + Value v(o_step); + ofstream os( "./stackTrace.json", ofstream::app); + os << write_string(v, true) << ","; os.close(); } }; From 8ecf06df863074e3c2009c0ed30540cb4fccc881 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 16 Dec 2014 20:17:23 +0100 Subject: [PATCH 217/277] FindCURL in out cmake folder, required to find debug curl library --- cmake/EthDependencies.cmake | 2 +- cmake/FindCURL.cmake | 49 +++++++++++++++++++++++++++++++++++++ cmake/FindGmp.cmake | 4 +-- 3 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 cmake/FindCURL.cmake diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index ee93a5311..136c86799 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -82,7 +82,7 @@ if (GMP_FOUND) endif() # curl is only requried for tests -# TODO specify min curl version, on windows we are currenly using 7.29 +# TODO specify min curl version, on windows we are currently using 7.29 find_package (CURL) message(" - curl header: ${CURL_INCLUDE_DIRS}") message(" - curl lib : ${CURL_LIBRARIES}") diff --git a/cmake/FindCURL.cmake b/cmake/FindCURL.cmake new file mode 100644 index 000000000..ba6603784 --- /dev/null +++ b/cmake/FindCURL.cmake @@ -0,0 +1,49 @@ +# Find CURL +# +# Find the curl includes and library +# +# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH +# +# This module defines +# CURL_INCLUDE_DIRS, where to find header, etc. +# CURL_LIBRARIES, the libraries needed to use curl. +# CURL_FOUND, If false, do not try to use curl. + +# only look in default directories +find_path( + CURL_INCLUDE_DIR + NAMES curl/curl.h + DOC "curl include dir" +) + +find_library( + CURL_LIBRARY + # names from cmake's FindCURL + NAMES curl curllib libcurl_imp curllib_static libcurl + DOC "curl library" +) + +set(CURL_INCLUDE_DIRS ${CURL_INCLUDE_DIR}) +set(CURL_LIBRARIES ${CURL_LIBRARY}) + +# debug library on windows +# same naming convention as in qt (appending debug library with d) +# boost is using the same "hack" as us with "optimized" and "debug" +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + find_library( + CURL_LIBRARY_DEBUG + NAMES curld libcurld + DOC "curl debug library" + ) + + set(CURL_LIBRARIES optimized ${CURL_LIBRARIES} debug ${CURL_LIBRARY_DEBUG}) + +endif() + +# handle the QUIETLY and REQUIRED arguments and set CURL_FOUND to TRUE +# if all listed variables are TRUE, hide their existence from configuration view +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(CURL DEFAULT_MSG + CURL_INCLUDE_DIR CURL_LIBRARY) +mark_as_advanced (CURL_INCLUDE_DIR CURL_LIBRARY) + diff --git a/cmake/FindGmp.cmake b/cmake/FindGmp.cmake index 1cffa7efa..4570b35fa 100644 --- a/cmake/FindGmp.cmake +++ b/cmake/FindGmp.cmake @@ -14,13 +14,13 @@ find_path( GMP_INCLUDE_DIR NAMES gmp.h DOC "gmp include dir" - ) +) find_library( GMP_LIBRARY NAMES gmp DOC "gmp library" - ) +) set(GMP_INCLUDE_DIRS ${GMP_INCLUDE_DIR}) set(GMP_LIBRARIES ${GMP_LIBRARY}) From 99dce392b03edc5ec5e27039fac6e039953581ed Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 16 Dec 2014 20:53:48 +0100 Subject: [PATCH 218/277] find jsonrpccpp debug libraries --- cmake/FindJsonRpcCpp.cmake | 47 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/cmake/FindJsonRpcCpp.cmake b/cmake/FindJsonRpcCpp.cmake index 3072ff244..2ca176f68 100644 --- a/cmake/FindJsonRpcCpp.cmake +++ b/cmake/FindJsonRpcCpp.cmake @@ -43,6 +43,53 @@ set (JSON_RPC_CPP_LIBRARIES ${JSON_RPC_CPP_COMMON_LIBRARY} ${JSON_RPC_CPP_SERVER set (JSON_RPC_CPP_SERVER_LIBRARIES ${JSON_RPC_CPP_COMMON_LIBRARY} ${JSON_RPC_CPP_SERVER_LIBRARY}) set (JSON_RPC_CPP_CLIENT_LIBRARIES ${JSON_RPC_CPP_COMMON_LIBRARY} ${JSON_RPC_CPP_CLIENT_LIBRARY}) +# debug library on windows +# same naming convention as in qt (appending debug library with d) +# boost is using the same "hack" as us with "optimized" and "debug" +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + find_library( + JSON_RPC_CPP_COMMON_LIBRARY_DEBUG + NAMES jsonrpccpp-commond + DOC "json-rpc-cpp common debug library" + ) + + find_library( + JSON_RPC_CPP_SERVER_LIBRARY_DEBUG + NAMES jsonrpccpp-serverd + DOC "json-rpc-cpp server debug library" + ) + + find_library( + JSON_RPC_CPP_CLIENT_LIBRARY_DEBUG + NAMES jsonrpccpp-clientd + DOC "json-rpc-cpp client debug library" + ) + + set (JSON_RPC_CPP_LIBRARIES + optimized ${JSON_RPC_CPP_COMMON_LIBRARY} + optimized ${JSON_RPC_CPP_SERVER_LIBRARY} + optimized ${JSON_RPC_CPP_CLIENT_LIBRARY} + debug ${JSON_RPC_CPP_COMMON_LIBRARY_DEBUG} + debug ${JSON_RPC_CPP_SERVER_LIBRARY_DEBUG} + debug ${JSON_RPC_CPP_CLIENT_LIBRARY_DEBUG} + ) + + set (JSON_RPC_CPP_SERVER_LIBRARIES + optimized ${JSON_RPC_CPP_COMMON_LIBRARY} + optimized ${JSON_RPC_CPP_SERVER_LIBRARY} + debug ${JSON_RPC_CPP_COMMON_LIBRARY_DEBUG} + debug ${JSON_RPC_CPP_SERVER_LIBRARY_DEBUG} + ) + + set (JSON_RPC_CPP_CLIENT_LIBRARIES + optimized ${JSON_RPC_CPP_COMMON_LIBRARY} + optimized ${JSON_RPC_CPP_CLIENT_LIBRARY} + debug ${JSON_RPC_CPP_COMMON_LIBRARY_DEBUG} + debug ${JSON_RPC_CPP_CLIENT_LIBRARY_DEBUG} + ) + +endif() + # handle the QUIETLY and REQUIRED arguments and set JSON_RPC_CPP_FOUND to TRUE # if all listed variables are TRUE, hide their existence from configuration view include(FindPackageHandleStandardArgs) From 28409ed583eda067619a36832db8866af8593ac2 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Tue, 16 Dec 2014 23:08:25 +0100 Subject: [PATCH 219/277] Fix for unhandled solc exception with opcodes argument - This should fix #631 --- solc/CommandLineInterface.cpp | 51 +++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 6ace332f7..f13423edb 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -43,6 +43,16 @@ using namespace std; namespace po = boost::program_options; +// LTODO: Maybe some argument class pairing names with +// extensions and other attributes would be a better choice here? +#define ARG_ABI_STR "abi" +#define ARG_ASM_STR "asm" +#define ARG_AST_STR "ast" +#define ARG_BINARY_STR "binary" +#define ARG_OPCODES_STR "opcodes" +#define ARG_NATSPECDEV_STR "natspec-dev" +#define ARG_NATSPECUSER_STR "natspec-user" + namespace dev { namespace solidity @@ -63,8 +73,9 @@ static inline bool argToStdout(po::variables_map const& _args, const char* _name static bool needStdout(po::variables_map const& _args) { - return argToStdout(_args, "abi") || argToStdout(_args, "natspec-user") || argToStdout(_args, "natspec-dev") || - argToStdout(_args, "asm") || argToStdout(_args, "opcodes") || argToStdout(_args, "binary"); + return argToStdout(_args, ARG_ABI_STR) || argToStdout(_args, ARG_NATSPECUSER_STR) || + argToStdout(_args, ARG_NATSPECDEV_STR) || argToStdout(_args, ARG_ASM_STR) || + argToStdout(_args, ARG_OPCODES_STR) || argToStdout(_args, ARG_BINARY_STR); } static inline bool outputToFile(OutputType type) @@ -94,7 +105,7 @@ static std::istream& operator>>(std::istream& _in, OutputType& io_output) void CommandLineInterface::handleBinary(string const& _contract) { - auto choice = m_args["binary"].as(); + auto choice = m_args[ARG_BINARY_STR].as(); if (outputToStdout(choice)) { cout << "Binary: " << endl; @@ -112,7 +123,7 @@ void CommandLineInterface::handleBinary(string const& _contract) void CommandLineInterface::handleOpcode(string const& _contract) { // TODO: Figure out why the wrong operator << (from boost) is used here - auto choice = m_args["opcode"].as(); + auto choice = m_args[ARG_OPCODES_STR].as(); if (outputToStdout(choice)) { cout << "Opcodes: " << endl; @@ -130,9 +141,9 @@ void CommandLineInterface::handleOpcode(string const& _contract) void CommandLineInterface::handleBytecode(string const& _contract) { - if (m_args.count("opcodes")) + if (m_args.count(ARG_OPCODES_STR)) handleOpcode(_contract); - if (m_args.count("binary")) + if (m_args.count(ARG_BINARY_STR)) handleBinary(_contract); } @@ -145,17 +156,17 @@ void CommandLineInterface::handleJson(DocumentationType _type, switch(_type) { case DocumentationType::ABI_INTERFACE: - argName = "abi"; + argName = ARG_ABI_STR; suffix = ".abi"; title = "Contract ABI"; break; case DocumentationType::NATSPEC_USER: - argName = "natspec-user"; + argName = "ARG_NATSPECUSER_STR"; suffix = ".docuser"; title = "User Documentation"; break; case DocumentationType::NATSPEC_DEV: - argName = "natspec-dev"; + argName = ARG_NATSPECDEV_STR; suffix = ".docdev"; title = "Developer Documentation"; break; @@ -195,19 +206,19 @@ bool CommandLineInterface::parseArguments(int argc, char** argv) ("version", "Show version and exit") ("optimize", po::value()->default_value(false), "Optimize bytecode for size") ("input-file", po::value>(), "input file") - ("ast", po::value(), + (ARG_AST_STR, po::value(), "Request to output the AST of the contract. " OUTPUT_TYPE_STR) - ("asm", po::value(), + (ARG_ASM_STR, po::value(), "Request to output the EVM assembly of the contract. " OUTPUT_TYPE_STR) - ("opcodes", po::value(), + (ARG_OPCODES_STR, po::value(), "Request to output the Opcodes of the contract. " OUTPUT_TYPE_STR) - ("binary", po::value(), + (ARG_BINARY_STR, po::value(), "Request to output the contract in binary (hexadecimal). " OUTPUT_TYPE_STR) - ("abi", po::value(), + (ARG_ABI_STR, po::value(), "Request to output the contract's ABI interface. " OUTPUT_TYPE_STR) - ("natspec-user", po::value(), + (ARG_NATSPECUSER_STR, po::value(), "Request to output the contract's Natspec user documentation. " OUTPUT_TYPE_STR) - ("natspec-dev", po::value(), + (ARG_NATSPECDEV_STR, po::value(), "Request to output the contract's Natspec developer documentation. " OUTPUT_TYPE_STR); #undef OUTPUT_TYPE_STR @@ -321,9 +332,9 @@ bool CommandLineInterface::processInput() void CommandLineInterface::actOnInput() { // do we need AST output? - if (m_args.count("ast")) + if (m_args.count(ARG_AST_STR)) { - auto choice = m_args["ast"].as(); + auto choice = m_args[ARG_AST_STR].as(); if (outputToStdout(choice)) { cout << "Syntax trees:" << endl << endl; @@ -355,9 +366,9 @@ void CommandLineInterface::actOnInput() cout << endl << "======= " << contract << " =======" << endl; // do we need EVM assembly? - if (m_args.count("asm")) + if (m_args.count(ARG_ASM_STR)) { - auto choice = m_args["asm"].as(); + auto choice = m_args[ARG_ASM_STR].as(); if (outputToStdout(choice)) { cout << "EVM assembly:" << endl; From b95b6f3b6630bce6ecb73cdf20a58059276df488 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Tue, 16 Dec 2014 23:31:22 +0100 Subject: [PATCH 220/277] Properly outputing opcodes in solc, using normal stream operator --- solc/CommandLineInterface.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index f13423edb..8aa182b5c 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -122,19 +122,18 @@ void CommandLineInterface::handleBinary(string const& _contract) void CommandLineInterface::handleOpcode(string const& _contract) { - // TODO: Figure out why the wrong operator << (from boost) is used here auto choice = m_args[ARG_OPCODES_STR].as(); if (outputToStdout(choice)) { cout << "Opcodes: " << endl; - dev::operator<<(cout, m_compiler.getBytecode(_contract)); + cout << eth::disassemble(m_compiler.getBytecode(_contract)); cout << endl; } if (outputToFile(choice)) { ofstream outFile(_contract + ".opcode"); - dev::operator<<(outFile, m_compiler.getBytecode(_contract)); + outFile << eth::disassemble(m_compiler.getBytecode(_contract)); outFile.close(); } } From 41948b13097a8fed084dbdc8ff970cf1d49c40b1 Mon Sep 17 00:00:00 2001 From: Christian Date: Tue, 16 Dec 2014 23:45:24 +0100 Subject: [PATCH 221/277] Fix: Resolve function types of all contracts before checking types inside functions. --- libsolidity/CompilerStack.cpp | 9 +++++++++ libsolidity/NameAndTypeResolver.cpp | 13 +++++++------ libsolidity/NameAndTypeResolver.h | 2 ++ test/solidityCompiler.cpp | 8 ++++++-- test/solidityExpressionCompiler.cpp | 7 ++++++- test/solidityNameAndTypeResolution.cpp | 18 ++++++++++++++++++ 6 files changed, 48 insertions(+), 9 deletions(-) diff --git a/libsolidity/CompilerStack.cpp b/libsolidity/CompilerStack.cpp index 23f5fd68f..1242c0aba 100644 --- a/libsolidity/CompilerStack.cpp +++ b/libsolidity/CompilerStack.cpp @@ -73,6 +73,15 @@ void CompilerStack::parse() resolver.resolveNamesAndTypes(*contract); m_contracts[contract->getName()].contract = contract; } + for (Source const* source: m_sourceOrder) + for (ASTPointer const& node: source->ast->getNodes()) + if (ContractDefinition* contract = dynamic_cast(node.get())) + { + m_globalContext->setCurrentContract(*contract); + resolver.updateDeclaration(*m_globalContext->getCurrentThis()); + resolver.checkTypeRequirements(*contract); + m_contracts[contract->getName()].contract = contract; + } m_parseSuccessful = true; } diff --git a/libsolidity/NameAndTypeResolver.cpp b/libsolidity/NameAndTypeResolver.cpp index 2ad276801..80732615c 100644 --- a/libsolidity/NameAndTypeResolver.cpp +++ b/libsolidity/NameAndTypeResolver.cpp @@ -49,8 +49,6 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract) m_currentScope = &m_scopes[&_contract]; for (ASTPointer const& structDef: _contract.getDefinedStructs()) ReferencesResolver resolver(*structDef, *this, nullptr); - for (ASTPointer const& structDef: _contract.getDefinedStructs()) - structDef->checkValidityOfMembers(); for (ASTPointer const& variable: _contract.getStateVariables()) ReferencesResolver resolver(*variable, *this, nullptr); for (ASTPointer const& function: _contract.getDefinedFunctions()) @@ -59,13 +57,16 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract) ReferencesResolver referencesResolver(*function, *this, function->getReturnParameterList().get()); } - // First, the parameter types of all functions need to be resolved before we can check - // the types, since it is possible to call functions that are only defined later - // in the source. - _contract.checkTypeRequirements(); m_currentScope = &m_scopes[nullptr]; } +void NameAndTypeResolver::checkTypeRequirements(ContractDefinition& _contract) +{ + for (ASTPointer const& structDef: _contract.getDefinedStructs()) + structDef->checkValidityOfMembers(); + _contract.checkTypeRequirements(); +} + void NameAndTypeResolver::updateDeclaration(Declaration const& _declaration) { m_scopes[nullptr].registerDeclaration(_declaration, true); diff --git a/libsolidity/NameAndTypeResolver.h b/libsolidity/NameAndTypeResolver.h index 1ff9febf0..23ac5fe77 100644 --- a/libsolidity/NameAndTypeResolver.h +++ b/libsolidity/NameAndTypeResolver.h @@ -46,6 +46,8 @@ public: void registerDeclarations(SourceUnit& _sourceUnit); /// Resolves all names and types referenced from the given contract. void resolveNamesAndTypes(ContractDefinition& _contract); + /// Check all type requirements in the given contract. + void checkTypeRequirements(ContractDefinition& _contract); /// Updates the given global declaration (used for "this"). Not to be used with declarations /// that create their own scope. void updateDeclaration(Declaration const& _declaration); diff --git a/test/solidityCompiler.cpp b/test/solidityCompiler.cpp index 29f61454a..9ae8ff50b 100644 --- a/test/solidityCompiler.cpp +++ b/test/solidityCompiler.cpp @@ -52,9 +52,13 @@ bytes compileContract(const string& _sourceCode) resolver.registerDeclarations(*sourceUnit); for (ASTPointer const& node: sourceUnit->getNodes()) if (ContractDefinition* contract = dynamic_cast(node.get())) - { BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract)); - + for (ASTPointer const& node: sourceUnit->getNodes()) + if (ContractDefinition* contract = dynamic_cast(node.get())) + BOOST_REQUIRE_NO_THROW(resolver.checkTypeRequirements(*contract)); + for (ASTPointer const& node: sourceUnit->getNodes()) + if (ContractDefinition* contract = dynamic_cast(node.get())) + { Compiler compiler; compiler.compileContract(*contract, {}, {}); // debug diff --git a/test/solidityExpressionCompiler.cpp b/test/solidityExpressionCompiler.cpp index c05db25d4..2bdc38421 100644 --- a/test/solidityExpressionCompiler.cpp +++ b/test/solidityExpressionCompiler.cpp @@ -95,8 +95,13 @@ bytes compileFirstExpression(const string& _sourceCode, vector> _ resolver.registerDeclarations(*sourceUnit); for (ASTPointer const& node: sourceUnit->getNodes()) if (ContractDefinition* contract = dynamic_cast(node.get())) - { BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract)); + for (ASTPointer const& node: sourceUnit->getNodes()) + if (ContractDefinition* contract = dynamic_cast(node.get())) + BOOST_REQUIRE_NO_THROW(resolver.checkTypeRequirements(*contract)); + for (ASTPointer const& node: sourceUnit->getNodes()) + if (ContractDefinition* contract = dynamic_cast(node.get())) + { FirstExpressionExtractor extractor(*contract); BOOST_REQUIRE(extractor.getExpression() != nullptr); diff --git a/test/solidityNameAndTypeResolution.cpp b/test/solidityNameAndTypeResolution.cpp index 0ea6e51b9..0bda0a1fd 100644 --- a/test/solidityNameAndTypeResolution.cpp +++ b/test/solidityNameAndTypeResolution.cpp @@ -47,6 +47,9 @@ void parseTextAndResolveNames(std::string const& _source) for (ASTPointer const& node: sourceUnit->getNodes()) if (ContractDefinition* contract = dynamic_cast(node.get())) resolver.resolveNamesAndTypes(*contract); + for (ASTPointer const& node: sourceUnit->getNodes()) + if (ContractDefinition* contract = dynamic_cast(node.get())) + resolver.checkTypeRequirements(*contract); } } @@ -293,6 +296,21 @@ BOOST_AUTO_TEST_CASE(returns_in_constructor) BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); } +BOOST_AUTO_TEST_CASE(forward_function_reference) +{ + char const* text = "contract First {\n" + " function fun() returns (bool ret) {\n" + " return Second(1).fun(1, true, 3) > 0;\n" + " }\n" + "}\n" + "contract Second {\n" + " function fun(uint a, bool b, uint c) returns (uint ret) {\n" + " if (First(2).fun() == true) return 1;\n" + " }\n" + "}\n"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + BOOST_AUTO_TEST_SUITE_END() } From 4e83ba5ae148fdcf887e813e7d1aa45ece312666 Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 15 Dec 2014 22:57:39 +0100 Subject: [PATCH 222/277] Add functions needed by constructor. --- libsolidity/CallGraph.cpp | 65 ++++++++++++++++++++++ libsolidity/CallGraph.h | 53 ++++++++++++++++++ libsolidity/Compiler.cpp | 101 +++++++++++++++++++--------------- libsolidity/Compiler.h | 12 +++- test/solidityEndToEndTest.cpp | 17 ++++++ 5 files changed, 202 insertions(+), 46 deletions(-) create mode 100644 libsolidity/CallGraph.cpp create mode 100644 libsolidity/CallGraph.h diff --git a/libsolidity/CallGraph.cpp b/libsolidity/CallGraph.cpp new file mode 100644 index 000000000..48666ca7f --- /dev/null +++ b/libsolidity/CallGraph.cpp @@ -0,0 +1,65 @@ + +/* + This file is part of cpp-ethereum. + + cpp-ethereum 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. + + cpp-ethereum 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 cpp-ethereum. If not, see . +*/ +/** + * @author Christian + * @date 2014 + * Callgraph of functions inside a contract. + */ + +#include +#include + +using namespace std; + +namespace dev { +namespace solidity { + +void CallGraph::addFunction(FunctionDefinition const& _function) +{ + if (!m_functionsSeen.count(&_function)) + { + m_functionsSeen.insert(&_function); + m_workQueue.push(&_function); + } +} + +set const& CallGraph::getCalls() +{ + return m_functionsSeen; +} + +void CallGraph::computeCallGraph() +{ + while (!m_workQueue.empty()) + { + FunctionDefinition const* fun = m_workQueue.front(); + fun->accept(*this); + m_workQueue.pop(); + } +} + +bool CallGraph::visit(Identifier const& _identifier) +{ + FunctionDefinition const* fun = dynamic_cast(_identifier.getReferencedDeclaration()); + if (fun) + addFunction(*fun); + return true; +} + +} +} diff --git a/libsolidity/CallGraph.h b/libsolidity/CallGraph.h new file mode 100644 index 000000000..986e4dc4a --- /dev/null +++ b/libsolidity/CallGraph.h @@ -0,0 +1,53 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum 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. + + cpp-ethereum 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 cpp-ethereum. If not, see . +*/ +/** + * @author Christian + * @date 2014 + * Callgraph of functions inside a contract. + */ + +#include +#include +#include +#include + +namespace dev { +namespace solidity { + +/** + * Can be used to compute the graph of calls (or rather references) between functions of the same + * contract. Current functionality is limited to computing all functions that are directly + * or indirectly called by some functions. + */ +class CallGraph: private ASTConstVisitor +{ +public: + void addFunction(FunctionDefinition const& _function); + void computeCallGraph(); + + std::set const& getCalls(); + +private: + void addFunctionToQueue(FunctionDefinition const& _function); + virtual bool visit(Identifier const& _identifier) override; + + std::set m_functionsSeen; + std::queue m_workQueue; +}; + +} +} diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index f2877c1ce..0f85cda38 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -27,6 +27,7 @@ #include #include #include +#include using namespace std; @@ -37,68 +38,82 @@ void Compiler::compileContract(ContractDefinition const& _contract, vector const& _contracts) { m_context = CompilerContext(); // clear it just in case - m_context.setCompiledContracts(_contracts); - - for (MagicVariableDeclaration const* variable: _magicGlobals) - m_context.addMagicGlobal(*variable); + initializeContext(_contract, _magicGlobals, _contracts); for (ASTPointer const& function: _contract.getDefinedFunctions()) if (function->getName() != _contract.getName()) // don't add the constructor here m_context.addFunction(*function); - registerStateVariables(_contract); appendFunctionSelector(_contract); for (ASTPointer const& function: _contract.getDefinedFunctions()) if (function->getName() != _contract.getName()) // don't add the constructor here function->accept(*this); - packIntoContractCreator(_contract, _contracts); -} - -void Compiler::packIntoContractCreator(ContractDefinition const& _contract, - map const& _contracts) -{ + // Swap the runtime context with the creation-time context CompilerContext runtimeContext; - runtimeContext.setCompiledContracts(_contracts); swap(m_context, runtimeContext); + initializeContext(_contract, _magicGlobals, _contracts); + packIntoContractCreator(_contract, runtimeContext); +} +void Compiler::initializeContext(ContractDefinition const& _contract, vector const& _magicGlobals, + map const& _contracts) +{ + m_context.setCompiledContracts(_contracts); + for (MagicVariableDeclaration const* variable: _magicGlobals) + m_context.addMagicGlobal(*variable); registerStateVariables(_contract); +} - FunctionDefinition* constructor = nullptr; - for (ASTPointer const& function: _contract.getDefinedFunctions()) - if (function->getName() == _contract.getName()) - { - constructor = function.get(); - break; - } - eth::AssemblyItem sub = m_context.addSubroutine(runtimeContext.getAssembly()); - // stack contains sub size +void Compiler::packIntoContractCreator(ContractDefinition const& _contract, CompilerContext const& _runtimeContext) +{ + set neededFunctions; + FunctionDefinition const* constructor = _contract.getConstructor(); if (constructor) - { - eth::AssemblyItem returnTag = m_context.pushNewTag(); - m_context.addFunction(*constructor); // note that it cannot be called due to syntactic reasons - // copy constructor arguments from code to memory and then to stack, they are supplied after the actual program - unsigned argumentSize = 0; - for (ASTPointer const& var: constructor->getParameters()) - argumentSize += var->getType()->getCalldataEncodedSize(); - if (argumentSize > 0) - { - m_context << u256(argumentSize); - m_context.appendProgramSize(); - m_context << u256(1); // copy it to byte one as expected for ABI calls - m_context << eth::Instruction::CODECOPY; - appendCalldataUnpacker(*constructor, true); - } - //@todo calling other functions inside the constructor should either trigger a parse error - //or we should copy them here (register them above and call "accept") - detecting which - // functions are referenced / called needs to be done in a recursive way. - m_context.appendJumpTo(m_context.getFunctionEntryLabel(*constructor)); - constructor->accept(*this); - m_context << returnTag; - } + neededFunctions = getFunctionsNeededByConstructor(*constructor); + + for (FunctionDefinition const* fun: neededFunctions) + m_context.addFunction(*fun); + if (constructor) + appendConstructorCall(*constructor); + + eth::AssemblyItem sub = m_context.addSubroutine(_runtimeContext.getAssembly()); + // stack contains sub size m_context << eth::Instruction::DUP1 << sub << u256(0) << eth::Instruction::CODECOPY; m_context << u256(0) << eth::Instruction::RETURN; + + // note that we have to explicitly include all used functions because of absolute jump + // labels + for (FunctionDefinition const* fun: neededFunctions) + fun->accept(*this); +} + +void Compiler::appendConstructorCall(FunctionDefinition const& _constructor) +{ + eth::AssemblyItem returnTag = m_context.pushNewTag(); + // copy constructor arguments from code to memory and then to stack, they are supplied after the actual program + unsigned argumentSize = 0; + for (ASTPointer const& var: _constructor.getParameters()) + argumentSize += var->getType()->getCalldataEncodedSize(); + if (argumentSize > 0) + { + m_context << u256(argumentSize); + m_context.appendProgramSize(); + m_context << u256(1); // copy it to byte one as expected for ABI calls + m_context << eth::Instruction::CODECOPY; + appendCalldataUnpacker(_constructor, true); + } + m_context.appendJumpTo(m_context.getFunctionEntryLabel(_constructor)); + m_context << returnTag; +} + +set Compiler::getFunctionsNeededByConstructor(FunctionDefinition const& _constructor) +{ + CallGraph callgraph; + callgraph.addFunction(_constructor); + callgraph.computeCallGraph(); + return callgraph.getCalls(); } void Compiler::appendFunctionSelector(ContractDefinition const& _contract) diff --git a/libsolidity/Compiler.h b/libsolidity/Compiler.h index 57e40cdae..b30e85ae4 100644 --- a/libsolidity/Compiler.h +++ b/libsolidity/Compiler.h @@ -38,10 +38,16 @@ public: void streamAssembly(std::ostream& _stream) const { m_context.streamAssembly(_stream); } private: - /// Creates a new compiler context / assembly, packs the current code into the data part and + /// Registers the global objects and the non-function objects inside the contract with the context. + void initializeContext(ContractDefinition const& _contract, std::vector const& _magicGlobals, + std::map const& _contracts); + /// Adds the code that is run at creation time. Should be run after exchanging the run-time context + /// with a new and initialized context. /// adds the constructor code. - void packIntoContractCreator(ContractDefinition const& _contract, - std::map const& _contracts); + void packIntoContractCreator(ContractDefinition const& _contract, CompilerContext const& _runtimeContext); + void appendConstructorCall(FunctionDefinition const& _constructor); + /// Recursively searches the call graph and returns all functions needed by the constructor (including itself). + std::set getFunctionsNeededByConstructor(FunctionDefinition const& _constructor); void appendFunctionSelector(ContractDefinition const& _contract); /// Creates code that unpacks the arguments for the given function, from memory if /// @a _fromMemory is true, otherwise from call data. @returns the size of the data in bytes. diff --git a/test/solidityEndToEndTest.cpp b/test/solidityEndToEndTest.cpp index b6f63aa72..78926e94a 100644 --- a/test/solidityEndToEndTest.cpp +++ b/test/solidityEndToEndTest.cpp @@ -1038,6 +1038,23 @@ BOOST_AUTO_TEST_CASE(constructor_arguments) BOOST_REQUIRE(callContractFunction(1) == bytes({'a', 'b', 'c'})); } +BOOST_AUTO_TEST_CASE(functions_called_by_constructor) +{ + char const* sourceCode = R"( + contract Test { + string3 name; + bool flag; + function Test() { + setName("abc"); + } + function getName() returns (string3 ret) { return name; } + private: + function setName(string3 _name) { name = _name; } + })"; + compileAndRun(sourceCode); + BOOST_REQUIRE(callContractFunction(0) == bytes({'a', 'b', 'c'})); +} + BOOST_AUTO_TEST_SUITE_END() } From c99b38a4ed70e578065a59e0dd332474fac6e42d Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Tue, 16 Dec 2014 23:55:38 +0100 Subject: [PATCH 223/277] Using strings instead of #defined literals in solc --- solc/CommandLineInterface.cpp | 76 +++++++++++++++++------------------ 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 8aa182b5c..fd660a0ca 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -43,21 +43,21 @@ using namespace std; namespace po = boost::program_options; -// LTODO: Maybe some argument class pairing names with -// extensions and other attributes would be a better choice here? -#define ARG_ABI_STR "abi" -#define ARG_ASM_STR "asm" -#define ARG_AST_STR "ast" -#define ARG_BINARY_STR "binary" -#define ARG_OPCODES_STR "opcodes" -#define ARG_NATSPECDEV_STR "natspec-dev" -#define ARG_NATSPECUSER_STR "natspec-user" - namespace dev { namespace solidity { +// LTODO: Maybe some argument class pairing names with +// extensions and other attributes would be a better choice here? +static string const g_argAbiStr = "abi"; +static string const g_argAsmStr = "asm"; +static string const g_argAstStr = "ast"; +static string const g_argBinaryStr = "binary"; +static string const g_argOpcodesStr = "opcodes"; +static string const g_argNatspecDevStr = "natspec-dev"; +static string const g_argNatspecUserStr = "natspec-user"; + static void version() { cout << "solc, the solidity complier commandline interface " << dev::Version << endl @@ -66,16 +66,16 @@ static void version() exit(0); } -static inline bool argToStdout(po::variables_map const& _args, const char* _name) +static inline bool argToStdout(po::variables_map const& _args, string const& _name) { return _args.count(_name) && _args[_name].as() != OutputType::FILE; } static bool needStdout(po::variables_map const& _args) { - return argToStdout(_args, ARG_ABI_STR) || argToStdout(_args, ARG_NATSPECUSER_STR) || - argToStdout(_args, ARG_NATSPECDEV_STR) || argToStdout(_args, ARG_ASM_STR) || - argToStdout(_args, ARG_OPCODES_STR) || argToStdout(_args, ARG_BINARY_STR); + return argToStdout(_args, g_argAbiStr) || argToStdout(_args, g_argNatspecUserStr) || + argToStdout(_args, g_argNatspecDevStr) || argToStdout(_args, g_argAsmStr) || + argToStdout(_args, g_argOpcodesStr) || argToStdout(_args, g_argBinaryStr); } static inline bool outputToFile(OutputType type) @@ -105,7 +105,7 @@ static std::istream& operator>>(std::istream& _in, OutputType& io_output) void CommandLineInterface::handleBinary(string const& _contract) { - auto choice = m_args[ARG_BINARY_STR].as(); + auto choice = m_args[g_argBinaryStr].as(); if (outputToStdout(choice)) { cout << "Binary: " << endl; @@ -122,7 +122,7 @@ void CommandLineInterface::handleBinary(string const& _contract) void CommandLineInterface::handleOpcode(string const& _contract) { - auto choice = m_args[ARG_OPCODES_STR].as(); + auto choice = m_args[g_argOpcodesStr].as(); if (outputToStdout(choice)) { cout << "Opcodes: " << endl; @@ -140,9 +140,9 @@ void CommandLineInterface::handleOpcode(string const& _contract) void CommandLineInterface::handleBytecode(string const& _contract) { - if (m_args.count(ARG_OPCODES_STR)) + if (m_args.count(g_argOpcodesStr)) handleOpcode(_contract); - if (m_args.count(ARG_BINARY_STR)) + if (m_args.count(g_argBinaryStr)) handleBinary(_contract); } @@ -155,17 +155,17 @@ void CommandLineInterface::handleJson(DocumentationType _type, switch(_type) { case DocumentationType::ABI_INTERFACE: - argName = ARG_ABI_STR; + argName = g_argAbiStr; suffix = ".abi"; title = "Contract ABI"; break; case DocumentationType::NATSPEC_USER: - argName = "ARG_NATSPECUSER_STR"; + argName = "g_argNatspecUserStr"; suffix = ".docuser"; title = "User Documentation"; break; case DocumentationType::NATSPEC_DEV: - argName = ARG_NATSPECDEV_STR; + argName = g_argNatspecDevStr; suffix = ".docdev"; title = "Developer Documentation"; break; @@ -205,20 +205,20 @@ bool CommandLineInterface::parseArguments(int argc, char** argv) ("version", "Show version and exit") ("optimize", po::value()->default_value(false), "Optimize bytecode for size") ("input-file", po::value>(), "input file") - (ARG_AST_STR, po::value(), + (g_argAstStr.c_str(), po::value(), "Request to output the AST of the contract. " OUTPUT_TYPE_STR) - (ARG_ASM_STR, po::value(), - "Request to output the EVM assembly of the contract. " OUTPUT_TYPE_STR) - (ARG_OPCODES_STR, po::value(), - "Request to output the Opcodes of the contract. " OUTPUT_TYPE_STR) - (ARG_BINARY_STR, po::value(), - "Request to output the contract in binary (hexadecimal). " OUTPUT_TYPE_STR) - (ARG_ABI_STR, po::value(), - "Request to output the contract's ABI interface. " OUTPUT_TYPE_STR) - (ARG_NATSPECUSER_STR, po::value(), - "Request to output the contract's Natspec user documentation. " OUTPUT_TYPE_STR) - (ARG_NATSPECDEV_STR, po::value(), - "Request to output the contract's Natspec developer documentation. " OUTPUT_TYPE_STR); + (g_argAsmStr.c_str(), po::value(), + "Request to output the EVM assembly of the contract. " OUTPUT_TYPE_STR) + (g_argOpcodesStr.c_str(), po::value(), + "Request to output the Opcodes of the contract. " OUTPUT_TYPE_STR) + (g_argBinaryStr.c_str(), po::value(), + "Request to output the contract in binary (hexadecimal). " OUTPUT_TYPE_STR) + (g_argAbiStr.c_str(), po::value(), + "Request to output the contract's ABI interface. " OUTPUT_TYPE_STR) + (g_argNatspecUserStr.c_str(), po::value(), + "Request to output the contract's Natspec user documentation. " OUTPUT_TYPE_STR) + (g_argNatspecDevStr.c_str(), po::value(), + "Request to output the contract's Natspec developer documentation. " OUTPUT_TYPE_STR); #undef OUTPUT_TYPE_STR // All positional options should be interpreted as input files @@ -331,9 +331,9 @@ bool CommandLineInterface::processInput() void CommandLineInterface::actOnInput() { // do we need AST output? - if (m_args.count(ARG_AST_STR)) + if (m_args.count(g_argAstStr)) { - auto choice = m_args[ARG_AST_STR].as(); + auto choice = m_args[g_argAstStr].as(); if (outputToStdout(choice)) { cout << "Syntax trees:" << endl << endl; @@ -365,9 +365,9 @@ void CommandLineInterface::actOnInput() cout << endl << "======= " << contract << " =======" << endl; // do we need EVM assembly? - if (m_args.count(ARG_ASM_STR)) + if (m_args.count(g_argAsmStr)) { - auto choice = m_args[ARG_ASM_STR].as(); + auto choice = m_args[g_argAsmStr].as(); if (outputToStdout(choice)) { cout << "EVM assembly:" << endl; From 30c000d121dc0132a6c5abb9d6e3da96b4dfda4a Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Mon, 15 Dec 2014 17:45:18 +0100 Subject: [PATCH 224/277] Adding a ForStatement solidity AST Node. - Adding ForStatement node - Implemented Parsing for ForStatement - A simple parsing test for the ForStatement - Work in progress --- libsolidity/AST.cpp | 7 +++++ libsolidity/AST.h | 24 +++++++++++++++++ libsolidity/ASTForward.h | 1 + libsolidity/ASTPrinter.cpp | 12 +++++++++ libsolidity/ASTPrinter.h | 2 ++ libsolidity/ASTVisitor.h | 4 +++ libsolidity/AST_accept.h | 24 +++++++++++++++++ libsolidity/Compiler.cpp | 7 +++++ libsolidity/Compiler.h | 1 + libsolidity/Parser.cpp | 54 +++++++++++++++++++++++++++++++------- libsolidity/Parser.h | 6 +++++ libsolidity/grammar.txt | 1 + test/solidityParser.cpp | 28 ++++++++++++++++++++ 13 files changed, 162 insertions(+), 9 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 5e344eadb..c286c412b 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -130,6 +130,13 @@ void WhileStatement::checkTypeRequirements() m_body->checkTypeRequirements(); } +void ForStatement::checkTypeRequirements() +{ + // LTODO + m_condExpression->expectType(BoolType()); + m_body->checkTypeRequirements(); +} + void Return::checkTypeRequirements() { if (!m_expression) diff --git a/libsolidity/AST.h b/libsolidity/AST.h index 4bb623b49..297b7f4e9 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -509,6 +509,30 @@ private: ASTPointer m_body; }; +class ForStatement: public BreakableStatement +{ +public: + ForStatement(Location const& _location, + ASTPointer const& _initExpression, + ASTPointer const& _conditionExpression, + ASTPointer const& _loopExpression, + ASTPointer const& _body): + BreakableStatement(_location), + m_initExpression(_initExpression), + m_condExpression(_conditionExpression), + m_loopExpression(_loopExpression), + m_body(_body) {} + virtual void accept(ASTVisitor& _visitor) override; + virtual void accept(ASTConstVisitor& _visitor) const override; + virtual void checkTypeRequirements() override; + +private: + ASTPointer m_initExpression; + ASTPointer m_condExpression; + ASTPointer m_loopExpression; + ASTPointer m_body; +}; + class Continue: public Statement { public: diff --git a/libsolidity/ASTForward.h b/libsolidity/ASTForward.h index d6c4c9f44..c960fc8f0 100644 --- a/libsolidity/ASTForward.h +++ b/libsolidity/ASTForward.h @@ -52,6 +52,7 @@ class Block; class IfStatement; class BreakableStatement; class WhileStatement; +class ForStatement; class Continue; class Break; class Return; diff --git a/libsolidity/ASTPrinter.cpp b/libsolidity/ASTPrinter.cpp index 970822a9a..916fca1ef 100644 --- a/libsolidity/ASTPrinter.cpp +++ b/libsolidity/ASTPrinter.cpp @@ -150,6 +150,13 @@ bool ASTPrinter::visit(WhileStatement const& _node) return goDeeper(); } +bool ASTPrinter::visit(ForStatement const& _node) +{ + writeLine("ForStatement"); + printSourcePart(_node); + return goDeeper(); +} + bool ASTPrinter::visit(Continue const& _node) { writeLine("Continue"); @@ -360,6 +367,11 @@ void ASTPrinter::endVisit(WhileStatement const&) m_indentation--; } +void ASTPrinter::endVisit(ForStatement const&) +{ + m_indentation--; +} + void ASTPrinter::endVisit(Continue const&) { m_indentation--; diff --git a/libsolidity/ASTPrinter.h b/libsolidity/ASTPrinter.h index 15b65e3f0..fc5fb4acb 100644 --- a/libsolidity/ASTPrinter.h +++ b/libsolidity/ASTPrinter.h @@ -57,6 +57,7 @@ public: bool visit(IfStatement const& _node) override; bool visit(BreakableStatement const& _node) override; bool visit(WhileStatement const& _node) override; + bool visit(ForStatement const& _node) override; bool visit(Continue const& _node) override; bool visit(Break const& _node) override; bool visit(Return const& _node) override; @@ -90,6 +91,7 @@ public: void endVisit(IfStatement const&) override; void endVisit(BreakableStatement const&) override; void endVisit(WhileStatement const&) override; + void endVisit(ForStatement const&) override; void endVisit(Continue const&) override; void endVisit(Break const&) override; void endVisit(Return const&) override; diff --git a/libsolidity/ASTVisitor.h b/libsolidity/ASTVisitor.h index 5728cd3d0..33a8a3383 100644 --- a/libsolidity/ASTVisitor.h +++ b/libsolidity/ASTVisitor.h @@ -58,6 +58,7 @@ public: virtual bool visit(IfStatement&) { return true; } virtual bool visit(BreakableStatement&) { return true; } virtual bool visit(WhileStatement&) { return true; } + virtual bool visit(ForStatement&) { return true; } virtual bool visit(Continue&) { return true; } virtual bool visit(Break&) { return true; } virtual bool visit(Return&) { return true; } @@ -93,6 +94,7 @@ public: virtual void endVisit(IfStatement&) { } virtual void endVisit(BreakableStatement&) { } virtual void endVisit(WhileStatement&) { } + virtual void endVisit(ForStatement&) { } virtual void endVisit(Continue&) { } virtual void endVisit(Break&) { } virtual void endVisit(Return&) { } @@ -132,6 +134,7 @@ public: virtual bool visit(IfStatement const&) { return true; } virtual bool visit(BreakableStatement const&) { return true; } virtual bool visit(WhileStatement const&) { return true; } + virtual bool visit(ForStatement const&) { return true; } virtual bool visit(Continue const&) { return true; } virtual bool visit(Break const&) { return true; } virtual bool visit(Return const&) { return true; } @@ -167,6 +170,7 @@ public: virtual void endVisit(IfStatement const&) { } virtual void endVisit(BreakableStatement const&) { } virtual void endVisit(WhileStatement const&) { } + virtual void endVisit(ForStatement const&) { } virtual void endVisit(Continue const&) { } virtual void endVisit(Break const&) { } virtual void endVisit(Return const&) { } diff --git a/libsolidity/AST_accept.h b/libsolidity/AST_accept.h index e0454d33e..ffef6f8b2 100644 --- a/libsolidity/AST_accept.h +++ b/libsolidity/AST_accept.h @@ -267,6 +267,30 @@ void WhileStatement::accept(ASTConstVisitor& _visitor) const _visitor.endVisit(*this); } +void ForStatement::accept(ASTVisitor& _visitor) +{ + if (_visitor.visit(*this)) + { + m_initExpression->accept(_visitor); + m_condExpression->accept(_visitor); + m_loopExpression->accept(_visitor); + m_body->accept(_visitor); + } + _visitor.endVisit(*this); +} + +void ForStatement::accept(ASTConstVisitor& _visitor) const +{ + if (_visitor.visit(*this)) + { + m_initExpression->accept(_visitor); + m_condExpression->accept(_visitor); + m_loopExpression->accept(_visitor); + m_body->accept(_visitor); + } + _visitor.endVisit(*this); +} + void Continue::accept(ASTVisitor& _visitor) { _visitor.visit(*this); diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index f2877c1ce..a0cad5374 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -287,6 +287,13 @@ bool Compiler::visit(WhileStatement const& _whileStatement) return false; } +bool Compiler::visit(ForStatement const& _forStatement) +{ + // LTODO + (void) _forStatement; + return false; +} + bool Compiler::visit(Continue const&) { if (!m_continueTags.empty()) diff --git a/libsolidity/Compiler.h b/libsolidity/Compiler.h index 57e40cdae..c4f46d10f 100644 --- a/libsolidity/Compiler.h +++ b/libsolidity/Compiler.h @@ -53,6 +53,7 @@ private: virtual bool visit(FunctionDefinition const& _function) override; virtual bool visit(IfStatement const& _ifStatement) override; virtual bool visit(WhileStatement const& _whileStatement) override; + virtual bool visit(ForStatement const& _forStatement) override; virtual bool visit(Continue const& _continue) override; virtual bool visit(Break const& _break) override; virtual bool visit(Return const& _return) override; diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index 21651eb14..9941fbf43 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -304,6 +304,8 @@ ASTPointer Parser::parseStatement() return parseIfStatement(); case Token::WHILE: return parseWhileStatement(); + case Token::FOR: + return parseForStatement(); case Token::LBRACE: return parseBlock(); // starting from here, all statements must be terminated by a semicolon @@ -328,15 +330,7 @@ ASTPointer Parser::parseStatement() } break; default: - // distinguish between variable definition (and potentially assignment) and expression statement - // (which include assignments to other expressions and pre-declared variables) - // We have a variable definition if we get a keyword that specifies a type name, or - // in the case of a user-defined type, we have two identifiers following each other. - if (m_scanner->getCurrentToken() == Token::MAPPING || - m_scanner->getCurrentToken() == Token::VAR || - ((Token::isElementaryTypeName(m_scanner->getCurrentToken()) || - m_scanner->getCurrentToken() == Token::IDENTIFIER) && - m_scanner->peekNextToken() == Token::IDENTIFIER)) + if (peekVariableDefinition()) statement = parseVariableDefinition(); else // "ordinary" expression statement statement = parseExpressionStatement(); @@ -377,6 +371,34 @@ ASTPointer Parser::parseWhileStatement() return nodeFactory.createNode(condition, body); } +ASTPointer Parser::parseForStatement() +{ + ASTNodeFactory nodeFactory(*this); + expectToken(Token::FOR); + expectToken(Token::LPAREN); + ASTPointer initExpression = parseVardefOrExprstatement(); + expectToken(Token::SEMICOLON); + ASTPointer conditionExpression = parseExpression(); + expectToken(Token::SEMICOLON); + ASTPointer loopExpression = parseExpressionStatement(); + expectToken(Token::SEMICOLON); + expectToken(Token::RPAREN); + ASTPointer body = parseStatement(); + nodeFactory.setEndPositionFromNode(body); + return nodeFactory.createNode(initExpression, + conditionExpression, + loopExpression, + body); +} + +ASTPointer Parser::parseVardefOrExprstatement() +{ + if (peekVariableDefinition()) + return parseVariableDefinition(); + else + return parseExpressionStatement(); +} + ASTPointer Parser::parseVariableDefinition() { ASTNodeFactory nodeFactory(*this); @@ -566,6 +588,20 @@ vector> Parser::parseFunctionCallArguments() return arguments; } + +// distinguish between variable definition (and potentially assignment) and expression statement +// (which include assignments to other expressions and pre-declared variables) +// We have a variable definition if we get a keyword that specifies a type name, or +// in the case of a user-defined type, we have two identifiers following each other. +bool Parser::peekVariableDefinition() +{ + return (m_scanner->getCurrentToken() == Token::MAPPING || + m_scanner->getCurrentToken() == Token::VAR || + ((Token::isElementaryTypeName(m_scanner->getCurrentToken()) || + m_scanner->getCurrentToken() == Token::IDENTIFIER) && + m_scanner->peekNextToken() == Token::IDENTIFIER)); +} + void Parser::expectToken(Token::Value _value) { if (m_scanner->getCurrentToken() != _value) diff --git a/libsolidity/Parser.h b/libsolidity/Parser.h index 52a374e03..343a85c0e 100644 --- a/libsolidity/Parser.h +++ b/libsolidity/Parser.h @@ -59,6 +59,8 @@ private: ASTPointer parseStatement(); ASTPointer parseIfStatement(); ASTPointer parseWhileStatement(); + ASTPointer parseForStatement(); + ASTPointer parseVardefOrExprstatement(); ASTPointer parseVariableDefinition(); ASTPointer parseExpressionStatement(); ASTPointer parseExpression(); @@ -72,6 +74,10 @@ private: ///@{ ///@name Helper functions + /// Peeks ahead in the scanner to determine if an expression statement + /// could be a variable definition + bool peekVariableDefinition(); + /// If current token value is not _value, throw exception otherwise advance token. void expectToken(Token::Value _value); Token::Value expectAssignmentOperator(); diff --git a/libsolidity/grammar.txt b/libsolidity/grammar.txt index a26f717a1..99a590014 100644 --- a/libsolidity/grammar.txt +++ b/libsolidity/grammar.txt @@ -20,6 +20,7 @@ Statement = IfStatement | WhileStatement | Block | IfStatement = 'if' '(' Expression ')' Statement ( 'else' Statement )? WhileStatement = 'while' '(' Expression ')' Statement +ForStatement = 'for' '(' Expressionstatement Expression Expressionstatement ')' Statement Continue = 'continue' ';' Break = 'break' ';' Return = 'return' Expression? ';' diff --git a/test/solidityParser.cpp b/test/solidityParser.cpp index a9e2d531f..8268901be 100644 --- a/test/solidityParser.cpp +++ b/test/solidityParser.cpp @@ -49,6 +49,23 @@ ASTPointer parseText(std::string const& _source) BOOST_FAIL("No contract found in source."); return ASTPointer(); } + +ASTPointer parseTextExplainError(std::string const& _source) +{ + try + { + return parseText(_source); + } + catch (Exception const& exception) + { + // LTODO: Print the error in a kind of a better way? + // In absence of CompilerStack we can't use SourceReferenceFormatter + cout << "Exception while parsing: " << diagnostic_information(exception); + // rethrow to signal test failure + throw exception; + } +} + } @@ -357,6 +374,17 @@ BOOST_AUTO_TEST_CASE(while_loop) BOOST_CHECK_NO_THROW(parseText(text)); } +BOOST_AUTO_TEST_CASE(for_loop) +{ + char const* text = "contract test {\n" + " function fun(uint256 a) {\n" + " for (uint256 i = 0; i < 10; i++;)\n" + " { uint256 x = i; break; continue; }\n" + " }\n" + "}\n"; + BOOST_CHECK_NO_THROW(parseTextExplainError(text)); +} + BOOST_AUTO_TEST_CASE(if_statement) { char const* text = "contract test {\n" From e934aa0befb759ae3fafb545dd9398833a49bbe7 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Mon, 15 Dec 2014 17:54:29 +0100 Subject: [PATCH 225/277] new ForStatement parsing test and small grammar fix --- libsolidity/Parser.cpp | 1 - libsolidity/grammar.txt | 2 +- test/solidityParser.cpp | 16 ++++++++++++++-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index 9941fbf43..d936cfc72 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -381,7 +381,6 @@ ASTPointer Parser::parseForStatement() ASTPointer conditionExpression = parseExpression(); expectToken(Token::SEMICOLON); ASTPointer loopExpression = parseExpressionStatement(); - expectToken(Token::SEMICOLON); expectToken(Token::RPAREN); ASTPointer body = parseStatement(); nodeFactory.setEndPositionFromNode(body); diff --git a/libsolidity/grammar.txt b/libsolidity/grammar.txt index 99a590014..76e7bb6b6 100644 --- a/libsolidity/grammar.txt +++ b/libsolidity/grammar.txt @@ -20,7 +20,7 @@ Statement = IfStatement | WhileStatement | Block | IfStatement = 'if' '(' Expression ')' Statement ( 'else' Statement )? WhileStatement = 'while' '(' Expression ')' Statement -ForStatement = 'for' '(' Expressionstatement Expression Expressionstatement ')' Statement +ForStatement = 'for' '(' VardefOrExpressionstatement ';' Expression ';' Expressionstatement ')' Statement Continue = 'continue' ';' Break = 'break' ';' Return = 'return' Expression? ';' diff --git a/test/solidityParser.cpp b/test/solidityParser.cpp index 8268901be..53bd3f163 100644 --- a/test/solidityParser.cpp +++ b/test/solidityParser.cpp @@ -374,11 +374,23 @@ BOOST_AUTO_TEST_CASE(while_loop) BOOST_CHECK_NO_THROW(parseText(text)); } -BOOST_AUTO_TEST_CASE(for_loop) +BOOST_AUTO_TEST_CASE(for_loop_vardef_initexpr) { char const* text = "contract test {\n" " function fun(uint256 a) {\n" - " for (uint256 i = 0; i < 10; i++;)\n" + " for (uint256 i = 0; i < 10; i++)\n" + " { uint256 x = i; break; continue; }\n" + " }\n" + "}\n"; + BOOST_CHECK_NO_THROW(parseTextExplainError(text)); +} + +BOOST_AUTO_TEST_CASE(for_loop_simple_initexpr) +{ + char const* text = "contract test {\n" + " function fun(uint256 a) {\n" + " uint256 i =0;\n" + " for (i = 0; i < 10; i++)\n" " { uint256 x = i; break; continue; }\n" " }\n" "}\n"; From b2992bd659768b0ee8f33ea24bf4e308efea3891 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Tue, 16 Dec 2014 09:51:51 +0100 Subject: [PATCH 226/277] Solidity ForStatements expressions are now optional --- libsolidity/AST_accept.h | 18 ++++++++++++------ libsolidity/Parser.cpp | 17 ++++++++++++++--- libsolidity/grammar.txt | 2 +- test/solidityParser.cpp | 12 ++++++++++++ 4 files changed, 39 insertions(+), 10 deletions(-) diff --git a/libsolidity/AST_accept.h b/libsolidity/AST_accept.h index ffef6f8b2..0e5a71b62 100644 --- a/libsolidity/AST_accept.h +++ b/libsolidity/AST_accept.h @@ -271,9 +271,12 @@ void ForStatement::accept(ASTVisitor& _visitor) { if (_visitor.visit(*this)) { - m_initExpression->accept(_visitor); - m_condExpression->accept(_visitor); - m_loopExpression->accept(_visitor); + if (m_initExpression) + m_initExpression->accept(_visitor); + if (m_condExpression) + m_condExpression->accept(_visitor); + if (m_loopExpression) + m_loopExpression->accept(_visitor); m_body->accept(_visitor); } _visitor.endVisit(*this); @@ -283,9 +286,12 @@ void ForStatement::accept(ASTConstVisitor& _visitor) const { if (_visitor.visit(*this)) { - m_initExpression->accept(_visitor); - m_condExpression->accept(_visitor); - m_loopExpression->accept(_visitor); + if (m_initExpression) + m_initExpression->accept(_visitor); + if (m_condExpression) + m_condExpression->accept(_visitor); + if (m_loopExpression) + m_loopExpression->accept(_visitor); m_body->accept(_visitor); } _visitor.endVisit(*this); diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index d936cfc72..598f5ad47 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -374,14 +374,25 @@ ASTPointer Parser::parseWhileStatement() ASTPointer Parser::parseForStatement() { ASTNodeFactory nodeFactory(*this); + ASTPointer initExpression; + ASTPointer conditionExpression; + ASTPointer loopExpression; expectToken(Token::FOR); expectToken(Token::LPAREN); - ASTPointer initExpression = parseVardefOrExprstatement(); + + // LTODO: Maybe here have some predicate like peekExpression() instead of checking for semicolon and RPAREN? + if (m_scanner->getCurrentToken() != Token::SEMICOLON) + initExpression = parseVardefOrExprstatement(); expectToken(Token::SEMICOLON); - ASTPointer conditionExpression = parseExpression(); + + if (m_scanner->getCurrentToken() != Token::SEMICOLON) + conditionExpression = parseExpression(); expectToken(Token::SEMICOLON); - ASTPointer loopExpression = parseExpressionStatement(); + + if (m_scanner->getCurrentToken() != Token::RPAREN) + loopExpression = parseExpressionStatement(); expectToken(Token::RPAREN); + ASTPointer body = parseStatement(); nodeFactory.setEndPositionFromNode(body); return nodeFactory.createNode(initExpression, diff --git a/libsolidity/grammar.txt b/libsolidity/grammar.txt index 76e7bb6b6..7c0ac3a50 100644 --- a/libsolidity/grammar.txt +++ b/libsolidity/grammar.txt @@ -20,7 +20,7 @@ Statement = IfStatement | WhileStatement | Block | IfStatement = 'if' '(' Expression ')' Statement ( 'else' Statement )? WhileStatement = 'while' '(' Expression ')' Statement -ForStatement = 'for' '(' VardefOrExpressionstatement ';' Expression ';' Expressionstatement ')' Statement +ForStatement = 'for' '(' (VardefOrExpressionstatement)? ';' (Expression)? ';' (Expressionstatement)? ')' Statement Continue = 'continue' ';' Break = 'break' ';' Return = 'return' Expression? ';' diff --git a/test/solidityParser.cpp b/test/solidityParser.cpp index 53bd3f163..d57754b61 100644 --- a/test/solidityParser.cpp +++ b/test/solidityParser.cpp @@ -397,6 +397,18 @@ BOOST_AUTO_TEST_CASE(for_loop_simple_initexpr) BOOST_CHECK_NO_THROW(parseTextExplainError(text)); } +BOOST_AUTO_TEST_CASE(for_loop_simple_noexpr) +{ + char const* text = "contract test {\n" + " function fun(uint256 a) {\n" + " uint256 i =0;\n" + " for (;;)\n" + " { uint256 x = i; break; continue; }\n" + " }\n" + "}\n"; + BOOST_CHECK_NO_THROW(parseTextExplainError(text)); +} + BOOST_AUTO_TEST_CASE(if_statement) { char const* text = "contract test {\n" From 5eec2c5ac6d5a7f543a9eb33bdb3365653146fa1 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Tue, 16 Dec 2014 13:20:50 +0100 Subject: [PATCH 227/277] ForStatement typecheck and initExpression is a Statement --- libsolidity/AST.cpp | 8 ++++++-- libsolidity/AST.h | 4 ++-- libsolidity/Parser.cpp | 4 ++-- libsolidity/Parser.h | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index c286c412b..4c042f2cf 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -132,8 +132,12 @@ void WhileStatement::checkTypeRequirements() void ForStatement::checkTypeRequirements() { - // LTODO - m_condExpression->expectType(BoolType()); + if (m_initExpression) + m_initExpression->checkTypeRequirements(); + if (m_condExpression) + m_condExpression->expectType(BoolType()); + if (m_loopExpression) + m_loopExpression->checkTypeRequirements(); m_body->checkTypeRequirements(); } diff --git a/libsolidity/AST.h b/libsolidity/AST.h index 297b7f4e9..2fb6a2e32 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -513,7 +513,7 @@ class ForStatement: public BreakableStatement { public: ForStatement(Location const& _location, - ASTPointer const& _initExpression, + ASTPointer const& _initExpression, ASTPointer const& _conditionExpression, ASTPointer const& _loopExpression, ASTPointer const& _body): @@ -527,7 +527,7 @@ public: virtual void checkTypeRequirements() override; private: - ASTPointer m_initExpression; + ASTPointer m_initExpression; ASTPointer m_condExpression; ASTPointer m_loopExpression; ASTPointer m_body; diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index 598f5ad47..2669ce209 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -374,7 +374,7 @@ ASTPointer Parser::parseWhileStatement() ASTPointer Parser::parseForStatement() { ASTNodeFactory nodeFactory(*this); - ASTPointer initExpression; + ASTPointer initExpression; ASTPointer conditionExpression; ASTPointer loopExpression; expectToken(Token::FOR); @@ -401,7 +401,7 @@ ASTPointer Parser::parseForStatement() body); } -ASTPointer Parser::parseVardefOrExprstatement() +ASTPointer Parser::parseVardefOrExprstatement() { if (peekVariableDefinition()) return parseVariableDefinition(); diff --git a/libsolidity/Parser.h b/libsolidity/Parser.h index 343a85c0e..cd3d5bab6 100644 --- a/libsolidity/Parser.h +++ b/libsolidity/Parser.h @@ -60,7 +60,7 @@ private: ASTPointer parseIfStatement(); ASTPointer parseWhileStatement(); ASTPointer parseForStatement(); - ASTPointer parseVardefOrExprstatement(); + ASTPointer parseVardefOrExprstatement(); ASTPointer parseVariableDefinition(); ASTPointer parseExpressionStatement(); ASTPointer parseExpression(); From 1f0346396ae307aa87e184f3ac8f0d7f9a97c832 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Tue, 16 Dec 2014 14:46:17 +0100 Subject: [PATCH 228/277] Minor issues, grammar update, new ForStatement test --- libsolidity/AST.h | 7 +++++++ libsolidity/Parser.cpp | 9 +++------ libsolidity/Parser.h | 5 ++--- libsolidity/grammar.txt | 6 ++++-- test/solidityParser.cpp | 12 ++++++++++++ 5 files changed, 28 insertions(+), 11 deletions(-) diff --git a/libsolidity/AST.h b/libsolidity/AST.h index 2fb6a2e32..dcbca1ee8 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -509,6 +509,9 @@ private: ASTPointer m_body; }; +/** + * For loop statement + */ class ForStatement: public BreakableStatement { public: @@ -527,9 +530,13 @@ public: virtual void checkTypeRequirements() override; private: + /// For statement's initialization expresion. for(XXX; ; ). Can be empty ASTPointer m_initExpression; + /// For statement's condition expresion. for(; XXX ; ). Can be empty ASTPointer m_condExpression; + /// For statement's loop expresion. for(;;XXX). Can be empty ASTPointer m_loopExpression; + /// The body of the loop ASTPointer m_body; }; diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index 2669ce209..732356751 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -330,10 +330,7 @@ ASTPointer Parser::parseStatement() } break; default: - if (peekVariableDefinition()) - statement = parseVariableDefinition(); - else // "ordinary" expression statement - statement = parseExpressionStatement(); + statement = parseVarDefOrExprStmt(); } expectToken(Token::SEMICOLON); return statement; @@ -382,7 +379,7 @@ ASTPointer Parser::parseForStatement() // LTODO: Maybe here have some predicate like peekExpression() instead of checking for semicolon and RPAREN? if (m_scanner->getCurrentToken() != Token::SEMICOLON) - initExpression = parseVardefOrExprstatement(); + initExpression = parseVarDefOrExprStmt(); expectToken(Token::SEMICOLON); if (m_scanner->getCurrentToken() != Token::SEMICOLON) @@ -401,7 +398,7 @@ ASTPointer Parser::parseForStatement() body); } -ASTPointer Parser::parseVardefOrExprstatement() +ASTPointer Parser::parseVarDefOrExprStmt() { if (peekVariableDefinition()) return parseVariableDefinition(); diff --git a/libsolidity/Parser.h b/libsolidity/Parser.h index cd3d5bab6..bf3a6beac 100644 --- a/libsolidity/Parser.h +++ b/libsolidity/Parser.h @@ -60,7 +60,7 @@ private: ASTPointer parseIfStatement(); ASTPointer parseWhileStatement(); ASTPointer parseForStatement(); - ASTPointer parseVardefOrExprstatement(); + ASTPointer parseVarDefOrExprStmt(); ASTPointer parseVariableDefinition(); ASTPointer parseExpressionStatement(); ASTPointer parseExpression(); @@ -74,8 +74,7 @@ private: ///@{ ///@name Helper functions - /// Peeks ahead in the scanner to determine if an expression statement - /// could be a variable definition + /// Peeks ahead in the scanner to determine if a variable definition is going to follow bool peekVariableDefinition(); /// If current token value is not _value, throw exception otherwise advance token. diff --git a/libsolidity/grammar.txt b/libsolidity/grammar.txt index 7c0ac3a50..8c34997b9 100644 --- a/libsolidity/grammar.txt +++ b/libsolidity/grammar.txt @@ -16,11 +16,13 @@ Mapping = 'mapping' '(' ElementaryTypeName '=>' TypeName ')' Block = '{' Statement* '}' Statement = IfStatement | WhileStatement | Block | - ( Continue | Break | Return | VariableDefinition | Expression ) ';' + ( Continue | Break | Return | VariableDefinition | ExpressionStatement ) ';' +ExpressionStatement = Expression IfStatement = 'if' '(' Expression ')' Statement ( 'else' Statement )? WhileStatement = 'while' '(' Expression ')' Statement -ForStatement = 'for' '(' (VardefOrExpressionstatement)? ';' (Expression)? ';' (Expressionstatement)? ')' Statement +VardefOrExprStmt = Variabledefinition | ExpressionStatement +ForStatement = 'for' '(' (VardefOrExprStmt)? ';' (Expression)? ';' (ExpressionStatement)? ')' Statement Continue = 'continue' ';' Break = 'break' ';' Return = 'return' Expression? ';' diff --git a/test/solidityParser.cpp b/test/solidityParser.cpp index d57754b61..f978cdd9b 100644 --- a/test/solidityParser.cpp +++ b/test/solidityParser.cpp @@ -409,6 +409,18 @@ BOOST_AUTO_TEST_CASE(for_loop_simple_noexpr) BOOST_CHECK_NO_THROW(parseTextExplainError(text)); } +BOOST_AUTO_TEST_CASE(for_loop_single_stmt_body) +{ + char const* text = "contract test {\n" + " function fun(uint256 a) {\n" + " uint256 i =0;\n" + " for (i = 0; i < 10; i++)\n" + " continue;\n" + " }\n" + "}\n"; + BOOST_CHECK_NO_THROW(parseTextExplainError(text)); +} + BOOST_AUTO_TEST_CASE(if_statement) { char const* text = "contract test {\n" From 3c6e966160d828882d243ee37b52b23992891404 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Tue, 16 Dec 2014 16:52:47 +0100 Subject: [PATCH 229/277] Solidity ForStatement Compiler part - Work in progress --- libsolidity/AST.h | 5 +++++ libsolidity/Compiler.cpp | 31 +++++++++++++++++++++++++++++-- test/solidityEndToEndTest.cpp | 22 ++++++++++++++++++++++ 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/libsolidity/AST.h b/libsolidity/AST.h index dcbca1ee8..c83690443 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -529,6 +529,11 @@ public: virtual void accept(ASTConstVisitor& _visitor) const override; virtual void checkTypeRequirements() override; + Statement const* getInitializationExpression() const { return m_initExpression.get(); } + Expression const* getCondition() const { return m_condExpression.get(); } + ExpressionStatement const* getLoopExpression() const { return m_loopExpression.get(); } + Statement const& getBody() const { return *m_body; } + private: /// For statement's initialization expresion. for(XXX; ; ). Can be empty ASTPointer m_initExpression; diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index a0cad5374..8c70b2718 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -289,8 +289,35 @@ bool Compiler::visit(WhileStatement const& _whileStatement) bool Compiler::visit(ForStatement const& _forStatement) { - // LTODO - (void) _forStatement; + eth::AssemblyItem loopStart = m_context.newTag(); + eth::AssemblyItem loopEnd = m_context.newTag(); + m_continueTags.push_back(loopStart); + m_breakTags.push_back(loopEnd); + + if (_forStatement.getInitializationExpression()) + _forStatement.getInitializationExpression()->accept(*this); + + m_context << loopStart; + + // if there is no terminating condition in for, default is to always be true + if (_forStatement.getCondition()) + { + compileExpression(*_forStatement.getCondition()); + m_context << eth::Instruction::ISZERO; + m_context.appendConditionalJumpTo(loopEnd); + } + + _forStatement.getBody().accept(*this); + + // for's loop expression if existing + if (_forStatement.getLoopExpression()) + _forStatement.getLoopExpression()->accept(*this); + + m_context.appendJumpTo(loopStart); + m_context << loopEnd; + + m_continueTags.pop_back(); + m_breakTags.pop_back(); return false; } diff --git a/test/solidityEndToEndTest.cpp b/test/solidityEndToEndTest.cpp index b6f63aa72..32de9af46 100644 --- a/test/solidityEndToEndTest.cpp +++ b/test/solidityEndToEndTest.cpp @@ -176,6 +176,28 @@ BOOST_AUTO_TEST_CASE(nested_loops) testSolidityAgainstCppOnRange(0, nested_loops_cpp, 0, 12); } +BOOST_AUTO_TEST_CASE(for_loop) +{ + char const* sourceCode = "contract test {\n" + " function f(uint n) returns(uint nfac) {\n" + " nfac = 1;\n" + " for (var i = 2; i <= n; i++)\n" + " nfac *= 1;\n" + " }\n" + "}\n"; + compileAndRun(sourceCode); + + auto for_loop_cpp = [](u256 const& n) -> u256 + { + u256 nfac = 1; + for (auto i = 2; i <= n; i++) + nfac *= i; + return nfac; + }; + + testSolidityAgainstCppOnRange(0, for_loop_cpp, 0, 5); +} + BOOST_AUTO_TEST_CASE(calling_other_functions) { // note that the index of a function is its index in the sorted sequence of functions From 82117dc7dab431b2de6cfb73a6b17343ff71b57b Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Tue, 16 Dec 2014 17:35:00 +0100 Subject: [PATCH 230/277] Solidity: More tests for the ForStatement --- test/solidityEndToEndTest.cpp | 54 ++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/test/solidityEndToEndTest.cpp b/test/solidityEndToEndTest.cpp index 32de9af46..ecd3b63a3 100644 --- a/test/solidityEndToEndTest.cpp +++ b/test/solidityEndToEndTest.cpp @@ -182,7 +182,7 @@ BOOST_AUTO_TEST_CASE(for_loop) " function f(uint n) returns(uint nfac) {\n" " nfac = 1;\n" " for (var i = 2; i <= n; i++)\n" - " nfac *= 1;\n" + " nfac *= i;\n" " }\n" "}\n"; compileAndRun(sourceCode); @@ -198,6 +198,58 @@ BOOST_AUTO_TEST_CASE(for_loop) testSolidityAgainstCppOnRange(0, for_loop_cpp, 0, 5); } +BOOST_AUTO_TEST_CASE(for_loop_empty) +{ + char const* sourceCode = "contract test {\n" + " function f() returns(uint ret) {\n" + " ret = 1;\n" + " for (;;)\n" + " {\n" + " ret += 1;\n" + " if (ret >= 10) break;\n" + " }\n" + " }\n" + "}\n"; + compileAndRun(sourceCode); + + auto for_loop_empty_cpp = []() -> u256 + { + u256 ret = 1; + for (;;) + { + ret += 1; + if (ret >= 10) break; + } + return ret; + }; + + testSolidityAgainstCpp(0, for_loop_empty_cpp); +} + +BOOST_AUTO_TEST_CASE(for_loop_simple_init_expr) +{ + char const* sourceCode = "contract test {\n" + " function f(uint n) returns(uint nfac) {\n" + " nfac = 1;\n" + " uint256 i;\n" + " for (i = 2; i <= n; i++)\n" + " nfac *= i;\n" + " }\n" + "}\n"; + compileAndRun(sourceCode); + + auto for_loop_simple_init_expr_cpp = [](u256 const& n) -> u256 + { + u256 nfac = 1; + u256 i; + for (i = 2; i <= n; i++) + nfac *= i; + return nfac; + }; + + testSolidityAgainstCppOnRange(0, for_loop_simple_init_expr_cpp, 0, 5); +} + BOOST_AUTO_TEST_CASE(calling_other_functions) { // note that the index of a function is its index in the sorted sequence of functions From c9a032aad4f762d15f92135cd0135303de2ad43c Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Wed, 17 Dec 2014 00:17:38 +0100 Subject: [PATCH 231/277] better alignment of global string constants --- solc/CommandLineInterface.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index fd660a0ca..81dd25ec7 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -50,13 +50,13 @@ namespace solidity // LTODO: Maybe some argument class pairing names with // extensions and other attributes would be a better choice here? -static string const g_argAbiStr = "abi"; -static string const g_argAsmStr = "asm"; -static string const g_argAstStr = "ast"; -static string const g_argBinaryStr = "binary"; -static string const g_argOpcodesStr = "opcodes"; -static string const g_argNatspecDevStr = "natspec-dev"; -static string const g_argNatspecUserStr = "natspec-user"; +static string const g_argAbiStr = "abi"; +static string const g_argAsmStr = "asm"; +static string const g_argAstStr = "ast"; +static string const g_argBinaryStr = "binary"; +static string const g_argOpcodesStr = "opcodes"; +static string const g_argNatspecDevStr = "natspec-dev"; +static string const g_argNatspecUserStr = "natspec-user"; static void version() { From bcc263070b5851dfa432272d18b06ec32a6fb59c Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Wed, 17 Dec 2014 00:28:26 +0100 Subject: [PATCH 232/277] Moving comment to function body --- libsolidity/Parser.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index 732356751..e287319d2 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -596,12 +596,12 @@ vector> Parser::parseFunctionCallArguments() } -// distinguish between variable definition (and potentially assignment) and expression statement -// (which include assignments to other expressions and pre-declared variables) -// We have a variable definition if we get a keyword that specifies a type name, or -// in the case of a user-defined type, we have two identifiers following each other. bool Parser::peekVariableDefinition() { + // distinguish between variable definition (and potentially assignment) and expression statement + // (which include assignments to other expressions and pre-declared variables) + // We have a variable definition if we get a keyword that specifies a type name, or + // in the case of a user-defined type, we have two identifiers following each other. return (m_scanner->getCurrentToken() == Token::MAPPING || m_scanner->getCurrentToken() == Token::VAR || ((Token::isElementaryTypeName(m_scanner->getCurrentToken()) || From f9627b07dcb170a98f51c52da261ace8dfbebc67 Mon Sep 17 00:00:00 2001 From: ethdev Date: Wed, 17 Dec 2014 11:18:59 +0100 Subject: [PATCH 233/277] vs files added to gitignore --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ca18feb5b..c18d5a01d 100644 --- a/.gitignore +++ b/.gitignore @@ -18,11 +18,14 @@ ipch *.sdf *.opensdf *.suo +*.vcxproj +*.vcxproj.filters +*.sln # VIM stuff *.swp -#Xcode stuff +# Xcode stuff build_xc *.user From 373dbcaa5ffec342a870070c35ee01cb2993455e Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 17 Dec 2014 11:48:43 +0100 Subject: [PATCH 234/277] clang requires explicit initialization of map --- test/solidityCompiler.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/solidityCompiler.cpp b/test/solidityCompiler.cpp index 29f61454a..1bdafc599 100644 --- a/test/solidityCompiler.cpp +++ b/test/solidityCompiler.cpp @@ -56,7 +56,11 @@ bytes compileContract(const string& _sourceCode) BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract)); Compiler compiler; - compiler.compileContract(*contract, {}, {}); + + // clang requires explicit initialization of map + // http://stackoverflow.com/questions/17264067/chosen-constructor-is-explicit-in-copy-initialization-error-with-clang-4-2 + compiler.compileContract(*contract, {}, map{}); + // debug //compiler.streamAssembly(cout); return compiler.getAssembledBytecode(); From edb6072cc9c8bbf9d54ee0596e24c03b1f778681 Mon Sep 17 00:00:00 2001 From: ethdev Date: Wed, 17 Dec 2014 11:57:32 +0100 Subject: [PATCH 235/277] windows fix for initializer-list cannot convert to dev::bytes --- test/solidityEndToEndTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/solidityEndToEndTest.cpp b/test/solidityEndToEndTest.cpp index ecd3b63a3..1ac480da9 100644 --- a/test/solidityEndToEndTest.cpp +++ b/test/solidityEndToEndTest.cpp @@ -1108,7 +1108,7 @@ BOOST_AUTO_TEST_CASE(constructor_arguments) function getName() returns (string3 ret) { return h.getName(); } })"; compileAndRun(sourceCode, 0, "Main"); - BOOST_REQUIRE(callContractFunction(0) == bytes({0x01})); + BOOST_REQUIRE(callContractFunction(0) == bytes{0x01}); BOOST_REQUIRE(callContractFunction(1) == bytes({'a', 'b', 'c'})); } From 2daf84f1bd122861bbc9a0b6e8f1401a6abc4ceb Mon Sep 17 00:00:00 2001 From: ethdev Date: Wed, 17 Dec 2014 12:19:10 +0100 Subject: [PATCH 236/277] initializer-list fix --- test/solidityEndToEndTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/solidityEndToEndTest.cpp b/test/solidityEndToEndTest.cpp index 1ac480da9..ad277a389 100644 --- a/test/solidityEndToEndTest.cpp +++ b/test/solidityEndToEndTest.cpp @@ -1108,7 +1108,7 @@ BOOST_AUTO_TEST_CASE(constructor_arguments) function getName() returns (string3 ret) { return h.getName(); } })"; compileAndRun(sourceCode, 0, "Main"); - BOOST_REQUIRE(callContractFunction(0) == bytes{0x01}); + BOOST_REQUIRE(callContractFunction(0) == bytes({byte(0x01)})); BOOST_REQUIRE(callContractFunction(1) == bytes({'a', 'b', 'c'})); } From d09f6e8c9756d2bf21499b80056fcb9bfcc76b1f Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 17 Dec 2014 15:15:04 +0100 Subject: [PATCH 237/277] Whitespace change. --- libsolidity/CallGraph.cpp | 6 ++++-- libsolidity/CallGraph.h | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/libsolidity/CallGraph.cpp b/libsolidity/CallGraph.cpp index 48666ca7f..b30afb612 100644 --- a/libsolidity/CallGraph.cpp +++ b/libsolidity/CallGraph.cpp @@ -26,8 +26,10 @@ using namespace std; -namespace dev { -namespace solidity { +namespace dev +{ +namespace solidity +{ void CallGraph::addFunction(FunctionDefinition const& _function) { diff --git a/libsolidity/CallGraph.h b/libsolidity/CallGraph.h index 986e4dc4a..f7af64bff 100644 --- a/libsolidity/CallGraph.h +++ b/libsolidity/CallGraph.h @@ -25,8 +25,10 @@ #include #include -namespace dev { -namespace solidity { +namespace dev +{ +namespace solidity +{ /** * Can be used to compute the graph of calls (or rather references) between functions of the same From 46664c44b368f8471d16f607d8ad6467ec5dbf89 Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 17 Dec 2014 16:23:18 +0100 Subject: [PATCH 238/277] Assertions that throw InternalCompilerErrors. --- libsolidity/AST.cpp | 8 ++--- libsolidity/AST.h | 16 +++++----- libsolidity/CompilerContext.cpp | 20 +++++------- libsolidity/CompilerUtils.cpp | 6 ++-- libsolidity/ExpressionCompiler.cpp | 33 ++++++++----------- libsolidity/InterfaceHandler.cpp | 3 +- libsolidity/NameAndTypeResolver.cpp | 15 +++------ libsolidity/Scanner.cpp | 13 +++----- libsolidity/Token.h | 13 +++----- libsolidity/Types.cpp | 13 ++++---- libsolidity/Utils.h | 49 +++++++++++++++++++++++++++++ solc/CommandLineInterface.cpp | 3 +- 12 files changed, 107 insertions(+), 85 deletions(-) create mode 100644 libsolidity/Utils.h diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 4c042f2cf..1fa6d8f6f 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -21,7 +21,7 @@ */ #include - +#include #include #include #include @@ -145,8 +145,7 @@ void Return::checkTypeRequirements() { if (!m_expression) return; - if (asserts(m_returnParameters)) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Return parameters not assigned.")); + solAssert(m_returnParameters, "Return parameters not assigned."); if (m_returnParameters->getParameters().size() != 1) BOOST_THROW_EXCEPTION(createTypeError("Different number of arguments in return statement " "than in returns declaration.")); @@ -336,8 +335,7 @@ void IndexAccess::checkTypeRequirements() void Identifier::checkTypeRequirements() { - if (asserts(m_referencedDeclaration)) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Identifier not resolved.")); + solAssert(m_referencedDeclaration, "Identifier not resolved."); VariableDeclaration const* variable = dynamic_cast(m_referencedDeclaration); if (variable) diff --git a/libsolidity/AST.h b/libsolidity/AST.h index c83690443..b7c3dc6c0 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -364,7 +365,7 @@ public: explicit ElementaryTypeName(Location const& _location, Token::Value _type): TypeName(_location), m_type(_type) { - if (asserts(Token::isElementaryTypeName(_type))) BOOST_THROW_EXCEPTION(InternalCompilerError()); + solAssert(Token::isElementaryTypeName(_type), ""); } virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; @@ -575,8 +576,7 @@ public: void setFunctionReturnParameters(ParameterList& _parameters) { m_returnParameters = &_parameters; } ParameterList const& getFunctionReturnParameters() const { - if (asserts(m_returnParameters)) - BOOST_THROW_EXCEPTION(InternalCompilerError()); + solAssert(m_returnParameters, ""); return *m_returnParameters; } Expression const* getExpression() const { return m_expression.get(); } @@ -682,7 +682,7 @@ public: Expression(_location), m_leftHandSide(_leftHandSide), m_assigmentOperator(_assignmentOperator), m_rightHandSide(_rightHandSide) { - if (asserts(Token::isAssignmentOp(_assignmentOperator))) BOOST_THROW_EXCEPTION(InternalCompilerError()); + solAssert(Token::isAssignmentOp(_assignmentOperator), ""); } virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; @@ -710,7 +710,7 @@ public: Expression(_location), m_operator(_operator), m_subExpression(_subExpression), m_isPrefix(_isPrefix) { - if (asserts(Token::isUnaryOp(_operator))) BOOST_THROW_EXCEPTION(InternalCompilerError()); + solAssert(Token::isUnaryOp(_operator), ""); } virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; @@ -737,7 +737,7 @@ public: Token::Value _operator, ASTPointer const& _right): Expression(_location), m_left(_left), m_operator(_operator), m_right(_right) { - if (asserts(Token::isBinaryOp(_operator) || Token::isCompareOp(_operator))) BOOST_THROW_EXCEPTION(InternalCompilerError()); + solAssert(Token::isBinaryOp(_operator) || Token::isCompareOp(_operator), ""); } virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; @@ -799,7 +799,7 @@ public: std::vector> getArguments() const { return {m_arguments.begin(), m_arguments.end()}; } /// Returns the referenced contract. Can only be called after type checking. - ContractDefinition const* getContract() const { if (asserts(m_contract)) BOOST_THROW_EXCEPTION(InternalCompilerError()); else return m_contract; } + ContractDefinition const* getContract() const { solAssert(m_contract, ""); return m_contract; } private: ASTPointer m_contractName; @@ -894,7 +894,7 @@ public: ElementaryTypeNameExpression(Location const& _location, Token::Value _typeToken): PrimaryExpression(_location), m_typeToken(_typeToken) { - if (asserts(Token::isElementaryTypeName(_typeToken))) BOOST_THROW_EXCEPTION(InternalCompilerError()); + solAssert(Token::isElementaryTypeName(_typeToken), ""); } virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; diff --git a/libsolidity/CompilerContext.cpp b/libsolidity/CompilerContext.cpp index 47401436a..18357bf0c 100644 --- a/libsolidity/CompilerContext.cpp +++ b/libsolidity/CompilerContext.cpp @@ -27,8 +27,10 @@ using namespace std; -namespace dev { -namespace solidity { +namespace dev +{ +namespace solidity +{ void CompilerContext::addMagicGlobal(MagicVariableDeclaration const& _declaration) { @@ -65,8 +67,7 @@ void CompilerContext::addFunction(FunctionDefinition const& _function) bytes const& CompilerContext::getCompiledContract(const ContractDefinition& _contract) const { auto ret = m_compiledContracts.find(&_contract); - if (asserts(ret != m_compiledContracts.end())) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Compiled contract not found.")); + solAssert(ret != m_compiledContracts.end(), "Compiled contract not found."); return *ret->second; } @@ -78,16 +79,14 @@ bool CompilerContext::isLocalVariable(Declaration const* _declaration) const eth::AssemblyItem CompilerContext::getFunctionEntryLabel(FunctionDefinition const& _function) const { auto res = m_functionEntryLabels.find(&_function); - if (asserts(res != m_functionEntryLabels.end())) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Function entry label not found.")); + solAssert(res != m_functionEntryLabels.end(), "Function entry label not found."); return res->second.tag(); } unsigned CompilerContext::getBaseStackOffsetOfVariable(Declaration const& _declaration) const { auto res = m_localVariables.find(&_declaration); - if (asserts(res != m_localVariables.end())) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Variable not found on stack.")); + solAssert(res != m_localVariables.end(), "Variable not found on stack."); return m_localVariablesSize - res->second - 1; } @@ -99,12 +98,9 @@ unsigned CompilerContext::baseToCurrentStackOffset(unsigned _baseOffset) const u256 CompilerContext::getStorageLocationOfVariable(const Declaration& _declaration) const { auto it = m_stateVariables.find(&_declaration); - if (it == m_stateVariables.end()) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Variable not found in storage.")); + solAssert(it != m_stateVariables.end(), "Variable not found in storage."); return it->second; } - - } } diff --git a/libsolidity/CompilerUtils.cpp b/libsolidity/CompilerUtils.cpp index 9f474896e..680e9190b 100644 --- a/libsolidity/CompilerUtils.cpp +++ b/libsolidity/CompilerUtils.cpp @@ -39,8 +39,7 @@ void CompilerUtils::loadFromMemory(unsigned _offset, unsigned _bytes, bool _left return; } eth::Instruction load = _fromCalldata ? eth::Instruction::CALLDATALOAD : eth::Instruction::MLOAD; - if (asserts(_bytes <= 32)) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Memory load of more than 32 bytes requested.")); + solAssert(_bytes <= 32, "Memory load of more than 32 bytes requested."); if (_bytes == 32) m_context << u256(_offset) << load; else @@ -63,8 +62,7 @@ void CompilerUtils::storeInMemory(unsigned _offset, unsigned _bytes, bool _leftA m_context << eth::Instruction::POP; return; } - if (asserts(_bytes <= 32)) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Memory store of more than 32 bytes requested.")); + solAssert(_bytes <= 32, "Memory store of more than 32 bytes requested."); if (_bytes != 32 && !_leftAligned) // shift the value accordingly before storing m_context << (u256(1) << ((32 - _bytes) * 8)) << eth::Instruction::MUL; diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 743503bbf..f58c157d9 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -30,8 +30,10 @@ using namespace std; -namespace dev { -namespace solidity { +namespace dev +{ +namespace solidity +{ void ExpressionCompiler::compileExpression(CompilerContext& _context, Expression const& _expression, bool _optimize) { @@ -51,8 +53,7 @@ bool ExpressionCompiler::visit(Assignment const& _assignment) _assignment.getRightHandSide().accept(*this); appendTypeConversion(*_assignment.getRightHandSide().getType(), *_assignment.getType()); _assignment.getLeftHandSide().accept(*this); - if (asserts(m_currentLValue.isValid())) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("LValue not retrieved.")); + solAssert(m_currentLValue.isValid(), "LValue not retrieved."); Token::Value op = _assignment.getAssignmentOperator(); if (op != Token::ASSIGN) // compound assignment @@ -84,8 +85,7 @@ void ExpressionCompiler::endVisit(UnaryOperation const& _unaryOperation) break; case Token::DELETE: // delete // @todo semantics change for complex types - if (asserts(m_currentLValue.isValid())) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("LValue not retrieved.")); + solAssert(m_currentLValue.isValid(), "LValue not retrieved."); m_context << u256(0); if (m_currentLValue.storesReferenceOnStack()) @@ -95,8 +95,7 @@ void ExpressionCompiler::endVisit(UnaryOperation const& _unaryOperation) break; case Token::INC: // ++ (pre- or postfix) case Token::DEC: // -- (pre- or postfix) - if (asserts(m_currentLValue.isValid())) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("LValue not retrieved.")); + solAssert(m_currentLValue.isValid(), "LValue not retrieved."); m_currentLValue.retrieveValue(_unaryOperation); if (!_unaryOperation.isPrefixOperation()) { @@ -179,8 +178,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) if (_functionCall.isTypeConversion()) { //@todo struct construction - if (asserts(_functionCall.getArguments().size() == 1)) - BOOST_THROW_EXCEPTION(InternalCompilerError()); + solAssert(_functionCall.getArguments().size() == 1, ""); Expression const& firstArgument = *_functionCall.getArguments().front(); firstArgument.accept(*this); if (firstArgument.getType()->getCategory() == Type::Category::CONTRACT && @@ -195,8 +193,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) { FunctionType const& function = dynamic_cast(*_functionCall.getExpression().getType()); vector> arguments = _functionCall.getArguments(); - if (asserts(arguments.size() == function.getParameterTypes().size())) - BOOST_THROW_EXCEPTION(InternalCompilerError()); + solAssert(arguments.size() == function.getParameterTypes().size(), ""); switch (function.getLocation()) { @@ -282,12 +279,10 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) bool ExpressionCompiler::visit(NewExpression const& _newExpression) { ContractType const* type = dynamic_cast(_newExpression.getType().get()); - if (asserts(type)) - BOOST_THROW_EXCEPTION(InternalCompilerError()); + solAssert(type, ""); TypePointers const& types = type->getConstructorType()->getParameterTypes(); vector> arguments = _newExpression.getArguments(); - if (asserts(arguments.size() == types.size())) - BOOST_THROW_EXCEPTION(InternalCompilerError()); + solAssert(arguments.size() == types.size(), ""); // copy the contracts code into memory bytes const& bytecode = m_context.getCompiledContract(*_newExpression.getContract()); @@ -439,8 +434,7 @@ void ExpressionCompiler::endVisit(Literal const& _literal) void ExpressionCompiler::appendAndOrOperatorCode(BinaryOperation const& _binaryOperation) { Token::Value const op = _binaryOperation.getOperator(); - if (asserts(op == Token::OR || op == Token::AND)) - BOOST_THROW_EXCEPTION(InternalCompilerError()); + solAssert(op == Token::OR || op == Token::AND, ""); _binaryOperation.getLeftExpression().accept(*this); m_context << eth::Instruction::DUP1; @@ -592,8 +586,7 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio vector> const& _arguments, FunctionCallOptions const& _options) { - if (asserts(_arguments.size() == _functionType.getParameterTypes().size())) - BOOST_THROW_EXCEPTION(InternalCompilerError()); + solAssert(_arguments.size() == _functionType.getParameterTypes().size(), ""); unsigned dataOffset = _options.bare ? 0 : 1; // reserve one byte for the function index for (unsigned i = 0; i < _arguments.size(); ++i) diff --git a/libsolidity/InterfaceHandler.cpp b/libsolidity/InterfaceHandler.cpp index 1310f504a..c734fa38c 100644 --- a/libsolidity/InterfaceHandler.cpp +++ b/libsolidity/InterfaceHandler.cpp @@ -198,8 +198,7 @@ std::string::const_iterator InterfaceHandler::appendDocTagParam(std::string::con std::string::const_iterator _end) { // Should never be called with an empty vector - if (asserts(!m_params.empty())) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Internal: Tried to append to empty parameter")); + solAssert(!m_params.empty(), "Internal: Tried to append to empty parameter"); auto pair = m_params.back(); pair.second += " "; diff --git a/libsolidity/NameAndTypeResolver.cpp b/libsolidity/NameAndTypeResolver.cpp index 80732615c..3774537d1 100644 --- a/libsolidity/NameAndTypeResolver.cpp +++ b/libsolidity/NameAndTypeResolver.cpp @@ -70,8 +70,7 @@ void NameAndTypeResolver::checkTypeRequirements(ContractDefinition& _contract) void NameAndTypeResolver::updateDeclaration(Declaration const& _declaration) { m_scopes[nullptr].registerDeclaration(_declaration, true); - if (asserts(_declaration.getScope() == nullptr)) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Updated declaration outside global scope.")); + solAssert(_declaration.getScope() == nullptr, "Updated declaration outside global scope."); } Declaration const* NameAndTypeResolver::resolveName(ASTString const& _name, Declaration const* _scope) const @@ -133,8 +132,7 @@ void DeclarationRegistrationHelper::endVisit(VariableDefinition& _variableDefini { // Register the local variables with the function // This does not fit here perfectly, but it saves us another AST visit. - if (asserts(m_currentFunction)) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Variable definition without function.")); + solAssert(m_currentFunction, "Variable definition without function."); m_currentFunction->addLocalVariable(_variableDefinition.getDeclaration()); } @@ -149,15 +147,13 @@ void DeclarationRegistrationHelper::enterNewSubScope(Declaration const& _declara map::iterator iter; bool newlyAdded; tie(iter, newlyAdded) = m_scopes.emplace(&_declaration, DeclarationContainer(m_currentScope, &m_scopes[m_currentScope])); - if (asserts(newlyAdded)) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unable to add new scope.")); + solAssert(newlyAdded, "Unable to add new scope."); m_currentScope = &_declaration; } void DeclarationRegistrationHelper::closeCurrentScope() { - if (asserts(m_currentScope)) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Closed non-existing scope.")); + solAssert(m_currentScope, "Closed non-existing scope."); m_currentScope = m_scopes[m_currentScope].getEnclosingDeclaration(); } @@ -196,8 +192,7 @@ void ReferencesResolver::endVisit(VariableDeclaration& _variable) bool ReferencesResolver::visit(Return& _return) { - if (asserts(m_returnParameters)) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Return parameters not set.")); + solAssert(m_returnParameters, "Return parameters not set."); _return.setFunctionReturnParameters(*m_returnParameters); return true; } diff --git a/libsolidity/Scanner.cpp b/libsolidity/Scanner.cpp index 08bf744d4..1a21149a1 100644 --- a/libsolidity/Scanner.cpp +++ b/libsolidity/Scanner.cpp @@ -52,6 +52,7 @@ #include #include +#include #include using namespace std; @@ -249,8 +250,7 @@ Token::Value Scanner::scanDocumentationComment() Token::Value Scanner::skipMultiLineComment() { - if (asserts(m_char == '*')) - BOOST_THROW_EXCEPTION(InternalCompilerError()); + solAssert(m_char == '*', ""); advance(); while (!isSourcePastEndOfInput()) { @@ -597,8 +597,7 @@ Token::Value Scanner::scanNumber(char _charSeen) // scan exponent, if any if (m_char == 'e' || m_char == 'E') { - if (asserts(kind != HEX)) // 'e'/'E' must be scanned as part of the hex number - BOOST_THROW_EXCEPTION(InternalCompilerError()); + solAssert(kind != HEX, "'e'/'E' must be scanned as part of the hex number"); if (kind != DECIMAL) return Token::ILLEGAL; // scan exponent @@ -639,8 +638,7 @@ static Token::Value keywordOrIdentifierToken(string const& _input) Token::Value Scanner::scanIdentifierOrKeyword() { - if (asserts(isIdentifierStart(m_char))) - BOOST_THROW_EXCEPTION(InternalCompilerError()); + solAssert(isIdentifierStart(m_char), ""); LiteralScope literal(this, LITERAL_TYPE_STRING); addLiteralCharAndAdvance(); // Scan the rest of the identifier characters. @@ -662,8 +660,7 @@ char CharStream::advanceAndGet(size_t _chars) char CharStream::rollback(size_t _amount) { - if (asserts(m_pos >= _amount)) - BOOST_THROW_EXCEPTION(InternalCompilerError()); + solAssert(m_pos >= _amount, ""); m_pos -= _amount; return get(); } diff --git a/libsolidity/Token.h b/libsolidity/Token.h index 22378ae07..32656096a 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -44,6 +44,7 @@ #include #include +#include #include namespace dev @@ -344,8 +345,7 @@ public: // (e.g. "LT" for the token LT). static char const* getName(Value tok) { - if (asserts(tok < NUM_TOKENS)) - BOOST_THROW_EXCEPTION(InternalCompilerError()); + solAssert(tok < NUM_TOKENS, ""); return m_name[tok]; } @@ -360,8 +360,7 @@ public: static Value AssignmentToBinaryOp(Value op) { - if (asserts(isAssignmentOp(op) && op != ASSIGN)) - BOOST_THROW_EXCEPTION(InternalCompilerError()); + solAssert(isAssignmentOp(op) && op != ASSIGN, ""); return Token::Value(op + (BIT_OR - ASSIGN_BIT_OR)); } @@ -375,8 +374,7 @@ public: // have a (unique) string (e.g. an IDENTIFIER). static char const* toString(Value tok) { - if (asserts(tok < NUM_TOKENS)) - BOOST_THROW_EXCEPTION(InternalCompilerError()); + solAssert(tok < NUM_TOKENS, ""); return m_string[tok]; } @@ -384,8 +382,7 @@ public: // operators; returns 0 otherwise. static int precedence(Value tok) { - if (asserts(tok < NUM_TOKENS)) - BOOST_THROW_EXCEPTION(InternalCompilerError()); + solAssert(tok < NUM_TOKENS, ""); return m_precedence[tok]; } diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index eba11cb0d..71319c3ac 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -34,8 +35,7 @@ namespace solidity shared_ptr Type::fromElementaryTypeName(Token::Value _typeToken) { - if (asserts(Token::isElementaryTypeName(_typeToken))) - BOOST_THROW_EXCEPTION(InternalCompilerError()); + solAssert(Token::isElementaryTypeName(_typeToken), ""); if (Token::INT <= _typeToken && _typeToken <= Token::HASH256) { @@ -120,8 +120,8 @@ IntegerType::IntegerType(int _bits, IntegerType::Modifier _modifier): { if (isAddress()) m_bits = 160; - if (asserts(m_bits > 0 && m_bits <= 256 && m_bits % 8 == 0)) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid bit number for integer type: " + dev::toString(_bits))); + solAssert(m_bits > 0 && m_bits <= 256 && m_bits % 8 == 0, + "Invalid bit number for integer type: " + dev::toString(_bits)); } bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const @@ -215,9 +215,8 @@ shared_ptr StaticStringType::smallestTypeForLiteral(string con StaticStringType::StaticStringType(int _bytes): m_bytes(_bytes) { - if (asserts(m_bytes >= 0 && m_bytes <= 32)) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid byte number for static string type: " + - dev::toString(m_bytes))); + solAssert(m_bytes >= 0 && m_bytes <= 32, + "Invalid byte number for static string type: " + dev::toString(m_bytes)); } bool StaticStringType::isImplicitlyConvertibleTo(Type const& _convertTo) const diff --git a/libsolidity/Utils.h b/libsolidity/Utils.h new file mode 100644 index 000000000..8d6a3ab08 --- /dev/null +++ b/libsolidity/Utils.h @@ -0,0 +1,49 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum 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. + + cpp-ethereum 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 cpp-ethereum. If not, see . +*/ +/** + * @author Christian + * @date 2014 + * Solidity Utilities. + */ + +#pragma once + +#include +#include + +namespace dev +{ +namespace solidity +{ + +/// Assertion that throws an InternalCompilerError containing the given description if it is not met. +#define solAssert(CONDITION, DESCRIPTION) \ + ::dev::solidity::solAssertAux(CONDITION, DESCRIPTION, __LINE__, __FILE__, ETH_FUNC) + +inline void solAssertAux(bool _condition, std::string const& _errorDescription, unsigned _line, + char const* _file, char const* _function) +{ + if (!_condition) + ::boost::throw_exception( InternalCompilerError() + << errinfo_comment(_errorDescription) + << ::boost::throw_function(_function) + << ::boost::throw_file(_file) + << ::boost::throw_line(_line)); +} + +} +} diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 81dd25ec7..399f52436 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -311,7 +311,8 @@ bool CommandLineInterface::processInput() } catch (InternalCompilerError const& exception) { - SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Internal compiler error", m_compiler); + cerr << "Internal compiler error during compilation:" << endl + << boost::diagnostic_information(exception); return false; } catch (Exception const& exception) From 0f75aaf6e63fd1c22ddc0eb828af8874bc2cd018 Mon Sep 17 00:00:00 2001 From: ethdev Date: Wed, 17 Dec 2014 16:25:24 +0100 Subject: [PATCH 239/277] cpack nsis windows installer --- CMakeLists.txt | 26 +++++++++++++++++++++++++- cmake/EthExecutableHelper.cmake | 15 ++++++++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 02e3a1a05..1293b4427 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -156,4 +156,28 @@ add_test(NAME alltests WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/test COMMAND testet #unset(TARGET_PLATFORM CACHE) - +if (WIN32) + # packaging stuff + include(InstallRequiredSystemLibraries) + set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "ethereum") + set(CPACK_PACKAGE_VENDOR "ethereum.org") + set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md") + set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") + set(CPACK_PACKAGE_VERSION "0.7") + set(CPACK_GENERATOR "NSIS") + + # our stuff + set(CPACK_COMPONENT_ALETHZERO_GROUP "Applications") + set(CPACK_COMPONENT_THIRD_GROUP "Applications") + set(CPACK_COMPONENT_MIX_GROUP "Applications") + set(CPACK_COMPONENTS_ALL alethzero third mix) + + # nsis specific stuff + set(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} ethereum") + set(CPACK_NSIS_HELP_LINK "https://github.com/ethereum/cpp-ethereum") + set(CPACK_NSIS_URL_INFO_ABOUT "https://github.com/ethereum/cpp-ethereum") + set(CPACK_NSIS_CONTACT "ethereum.org") + set(CPACK_NSIS_MODIFY_PATH ON) + + include(CPack) +endif (WIN32) diff --git a/cmake/EthExecutableHelper.cmake b/cmake/EthExecutableHelper.cmake index 9d273522e..0ec1e10d4 100644 --- a/cmake/EthExecutableHelper.cmake +++ b/cmake/EthExecutableHelper.cmake @@ -108,7 +108,20 @@ macro(eth_install_executable EXECUTABLE) $/platforms ) - install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin) + install( FILES ${DLLS} + DESTINATION bin + COMPONENT ${EXECUTABLE} + ) + + install( DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/plugins/platforms + DESTINATION bin + COMPONENT ${EXECUTABLE} + ) + + install( TARGETS ${EXECUTABLE} RUNTIME + DESTINATION bin + COMPONENT ${EXECUTABLE} + ) else() install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin) From 8468d896a73b5ea44c94ca92afe78189044d8024 Mon Sep 17 00:00:00 2001 From: ethdev Date: Wed, 17 Dec 2014 16:47:22 +0100 Subject: [PATCH 240/277] fixed msvc not expanding macros correctly --- test/CMakeLists.txt | 1 + test/solidityCompiler.cpp | 7 ++++--- test/solidityExpressionCompiler.cpp | 4 ++++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f862de24c..7cedc117b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -3,6 +3,7 @@ cmake_policy(SET CMP0015 NEW) aux_source_directory(. SRC_LIST) list(REMOVE_ITEM SRC_LIST "./createRandomTest.cpp") +include_directories(${Boost_INCLUDE_DIRS}) include_directories(${CRYPTOPP_INCLUDE_DIRS}) include_directories(${JSONCPP_INCLUDE_DIRS}) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) diff --git a/test/solidityCompiler.cpp b/test/solidityCompiler.cpp index be2c83838..385a3e577 100644 --- a/test/solidityCompiler.cpp +++ b/test/solidityCompiler.cpp @@ -52,17 +52,18 @@ bytes compileContract(const string& _sourceCode) resolver.registerDeclarations(*sourceUnit); for (ASTPointer const& node: sourceUnit->getNodes()) if (ContractDefinition* contract = dynamic_cast(node.get())) + { BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract)); + } for (ASTPointer const& node: sourceUnit->getNodes()) if (ContractDefinition* contract = dynamic_cast(node.get())) + { BOOST_REQUIRE_NO_THROW(resolver.checkTypeRequirements(*contract)); + } for (ASTPointer const& node: sourceUnit->getNodes()) if (ContractDefinition* contract = dynamic_cast(node.get())) { Compiler compiler; - - // clang requires explicit initialization of map - // http://stackoverflow.com/questions/17264067/chosen-constructor-is-explicit-in-copy-initialization-error-with-clang-4-2 compiler.compileContract(*contract, {}, map{}); // debug diff --git a/test/solidityExpressionCompiler.cpp b/test/solidityExpressionCompiler.cpp index 2bdc38421..9c375418e 100644 --- a/test/solidityExpressionCompiler.cpp +++ b/test/solidityExpressionCompiler.cpp @@ -95,10 +95,14 @@ bytes compileFirstExpression(const string& _sourceCode, vector> _ resolver.registerDeclarations(*sourceUnit); for (ASTPointer const& node: sourceUnit->getNodes()) if (ContractDefinition* contract = dynamic_cast(node.get())) + { BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract)); + } for (ASTPointer const& node: sourceUnit->getNodes()) if (ContractDefinition* contract = dynamic_cast(node.get())) + { BOOST_REQUIRE_NO_THROW(resolver.checkTypeRequirements(*contract)); + } for (ASTPointer const& node: sourceUnit->getNodes()) if (ContractDefinition* contract = dynamic_cast(node.get())) { From 83b218908b8220aa47a3bb1ea8b2e3cdc60474b7 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 17 Dec 2014 17:08:57 +0100 Subject: [PATCH 241/277] Format catch arguments as function parameters. --- solc/CommandLineInterface.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 399f52436..2a79521ef 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -230,9 +230,9 @@ bool CommandLineInterface::parseArguments(int argc, char** argv) { po::store(po::command_line_parser(argc, argv).options(desc).positional(p).allow_unregistered().run(), m_args); } - catch (po::error const& exception) + catch (po::error const& _exception) { - cout << exception.what() << endl; + cout << _exception.what() << endl; return false; } po::notify(m_args); @@ -289,35 +289,35 @@ bool CommandLineInterface::processInput() // TODO: Perhaps we should not compile unless requested m_compiler.compile(m_args["optimize"].as()); } - catch (ParserError const& exception) + catch (ParserError const& _exception) { - SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Parser error", m_compiler); + SourceReferenceFormatter::printExceptionInformation(cerr, _exception, "Parser error", m_compiler); return false; } - catch (DeclarationError const& exception) + catch (DeclarationError const& _exception) { - SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Declaration error", m_compiler); + SourceReferenceFormatter::printExceptionInformation(cerr, _exception, "Declaration error", m_compiler); return false; } - catch (TypeError const& exception) + catch (TypeError const& _exception) { - SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Type error", m_compiler); + SourceReferenceFormatter::printExceptionInformation(cerr, _exception, "Type error", m_compiler); return false; } - catch (CompilerError const& exception) + catch (CompilerError const& _exception) { - SourceReferenceFormatter::printExceptionInformation(cerr, exception, "Compiler error", m_compiler); + SourceReferenceFormatter::printExceptionInformation(cerr, _exception, "Compiler error", m_compiler); return false; } - catch (InternalCompilerError const& exception) + catch (InternalCompilerError const& _exception) { cerr << "Internal compiler error during compilation:" << endl - << boost::diagnostic_information(exception); + << boost::diagnostic_information(_exception); return false; } - catch (Exception const& exception) + catch (Exception const& _exception) { - cerr << "Exception during compilation: " << boost::diagnostic_information(exception) << endl; + cerr << "Exception during compilation: " << boost::diagnostic_information(_exception) << endl; return false; } catch (...) From 6c1beee64d57b2ea8e5c5ecb9992806cb1cfe999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Wed, 17 Dec 2014 17:55:50 +0100 Subject: [PATCH 242/277] Update evmjit submodule --- evmjit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evmjit b/evmjit index dbf8174fc..b37ce8e97 160000 --- a/evmjit +++ b/evmjit @@ -1 +1 @@ -Subproject commit dbf8174fc6f8be9e6d1e62a627388fa23eb2308f +Subproject commit b37ce8e9727683b8c7afb84520f42a908318f8d8 From 2bff39d4870a6b8c57deb53fbdba2d22cdd0d01b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Wed, 17 Dec 2014 17:56:44 +0100 Subject: [PATCH 243/277] Visual Studio project files update --- windows/LibEthereum.vcxproj | 10 ++++------ windows/LibEthereum.vcxproj.filters | 30 ++++++++++++----------------- windows/TestEthereum.vcxproj | 1 + 3 files changed, 17 insertions(+), 24 deletions(-) diff --git a/windows/LibEthereum.vcxproj b/windows/LibEthereum.vcxproj index b4624f962..30c5e8a21 100644 --- a/windows/LibEthereum.vcxproj +++ b/windows/LibEthereum.vcxproj @@ -117,13 +117,12 @@ - - + - + @@ -335,13 +334,12 @@ - - + - + diff --git a/windows/LibEthereum.vcxproj.filters b/windows/LibEthereum.vcxproj.filters index e70393706..39c3a0004 100644 --- a/windows/LibEthereum.vcxproj.filters +++ b/windows/LibEthereum.vcxproj.filters @@ -58,18 +58,12 @@ libethereum - - libethereum - libethereum libethereum - - libethereum - libethereum @@ -136,9 +130,6 @@ libethereum - - libethereum - libethereum @@ -204,6 +195,12 @@ libp2p + + libethereum + + + libethereum + @@ -272,18 +269,12 @@ libethereum - - libethereum - libethereum libethereum - - libethereum - libethereum @@ -368,9 +359,6 @@ libethereum - - libethereum - libethereum @@ -449,6 +437,12 @@ libp2p + + libethereum + + + libethereum + diff --git a/windows/TestEthereum.vcxproj b/windows/TestEthereum.vcxproj index 93bb98e23..cc737bc31 100644 --- a/windows/TestEthereum.vcxproj +++ b/windows/TestEthereum.vcxproj @@ -111,6 +111,7 @@ Console true + 33554432 From a6e8c122ea88990eb6a0f9a26bfbe81c335b07c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Wed, 17 Dec 2014 17:56:54 +0100 Subject: [PATCH 244/277] Windows fix --- test/TestHelper.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index d0100db61..ea848c7ce 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -331,9 +331,11 @@ void checkStorage(map _expectedStore, map _resultStore, } } BOOST_CHECK_EQUAL(_resultStore.size(), _expectedStore.size()); - for (auto&& resultStorePair : _resultStore) + for (auto&& resultStorePair: _resultStore) + { if (!_expectedStore.count(resultStorePair.first)) BOOST_ERROR(_expectedAddr << ": unexpected store key " << resultStorePair.first); + } } void checkLog(LogEntries _resultLogs, LogEntries _expectedLogs) From 68b9c67e9577b80cba4b8900da36e4898198bb76 Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 17 Dec 2014 18:33:55 +0100 Subject: [PATCH 245/277] Return the last contract by default. --- libsolidity/CompilerStack.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libsolidity/CompilerStack.cpp b/libsolidity/CompilerStack.cpp index 1242c0aba..9fdc88baa 100644 --- a/libsolidity/CompilerStack.cpp +++ b/libsolidity/CompilerStack.cpp @@ -234,9 +234,13 @@ CompilerStack::Contract const& CompilerStack::getContract(string const& _contrac { if (m_contracts.empty()) BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("No compiled contracts found.")); + string contractName = _contractName; if (_contractName.empty()) - return m_contracts.begin()->second; - auto it = m_contracts.find(_contractName); + // try to find the "last contract" + for (ASTPointer const& node: m_sourceOrder.back()->ast->getNodes()) + if (auto contract = dynamic_cast(node.get())) + contractName = contract->getName(); + auto it = m_contracts.find(contractName); if (it == m_contracts.end()) BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Contract " + _contractName + " not found.")); return it->second; From 3f865244df4d145d8b12af9a0c95859c2608cd5a Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 17 Dec 2014 18:52:53 +0100 Subject: [PATCH 246/277] Fix warning about sequence points. --- libdevcrypto/Common.h | 2 +- libethereum/Transaction.cpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libdevcrypto/Common.h b/libdevcrypto/Common.h index 02d52f495..021f97de8 100644 --- a/libdevcrypto/Common.h +++ b/libdevcrypto/Common.h @@ -47,7 +47,7 @@ struct SignatureStruct { SignatureStruct() {} SignatureStruct(Signature const& _s) { *(h520*)this = _s; } - SignatureStruct(h256 _r, h256 _s, byte _v): r(_r), s(_s), v(_v) {} + SignatureStruct(h256 const& _r, h256 const& _s, byte _v): r(_r), s(_s), v(_v) {} operator Signature() const { return *(h520 const*)this; } /// @returns true if r,s,v values are valid, otherwise false diff --git a/libethereum/Transaction.cpp b/libethereum/Transaction.cpp index 1edfe3927..0c1173134 100644 --- a/libethereum/Transaction.cpp +++ b/libethereum/Transaction.cpp @@ -43,7 +43,10 @@ Transaction::Transaction(bytesConstRef _rlpData, bool _checkSender) m_receiveAddress = rlp[field = 3].toHash
(); m_value = rlp[field = 4].toInt(); m_data = rlp[field = 5].toBytes(); - m_vrs = SignatureStruct{ rlp[field = 7].toInt(), rlp[field = 8].toInt(), byte(rlp[field = 6].toInt() - 27) }; + h256 r = rlp[field = 7].toInt(); + h256 s = rlp[field = 8].toInt(); + byte v = rlp[field = 6].toInt() - 27; + m_vrs = SignatureStruct{ r, s, v }; if (_checkSender) m_sender = sender(); } From 7377e9388294b918a917691218f0b659a0d74edf Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 17 Dec 2014 19:20:36 +0100 Subject: [PATCH 247/277] Bugfix: Data reference tags can be longer than jump tags. --- libevmcore/Assembly.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/libevmcore/Assembly.cpp b/libevmcore/Assembly.cpp index 74bd015a6..5efbb9487 100644 --- a/libevmcore/Assembly.cpp +++ b/libevmcore/Assembly.cpp @@ -478,7 +478,6 @@ bytes Assembly::assemble() const bytes ret; unsigned totalBytes = bytesRequired(); - ret.reserve(totalBytes); vector tagPos(m_usedTags); map tagRef; multimap dataRef; @@ -489,6 +488,12 @@ bytes Assembly::assemble() const for (auto const& i: m_subs) m_data[i.first] = i.second.assemble(); + unsigned bytesRequiredIncludingData = bytesRequired(); + unsigned bytesPerDataRef = dev::bytesRequired(bytesRequiredIncludingData); + byte dataRefPush = (byte)Instruction::PUSH1 - 1 + bytesPerDataRef; + ret.reserve(bytesRequiredIncludingData); + // m_data must not change from here on + for (AssemblyItem const& i: m_items) switch (i.m_type) { @@ -526,9 +531,9 @@ bytes Assembly::assemble() const } case PushData: case PushSub: { - ret.push_back(tagPush); + ret.push_back(dataRefPush); dataRef.insert(make_pair((h256)i.m_data, ret.size())); - ret.resize(ret.size() + bytesPerTag); + ret.resize(ret.size() + bytesPerDataRef); break; } case PushSubSize: @@ -542,10 +547,12 @@ bytes Assembly::assemble() const break; } case PushProgramSize: - ret.push_back(tagPush); + { + ret.push_back(dataRefPush); sizeRef.push_back(ret.size()); - ret.resize(ret.size() + bytesPerTag); + ret.resize(ret.size() + bytesPerDataRef); break; + } case Tag: tagPos[(unsigned)i.m_data] = ret.size(); ret.push_back((byte)Instruction::JUMPDEST); @@ -573,7 +580,7 @@ bytes Assembly::assemble() const { for (auto it = its.first; it != its.second; ++it) { - bytesRef r(ret.data() + it->second, bytesPerTag); + bytesRef r(ret.data() + it->second, bytesPerDataRef); toBigEndian(ret.size(), r); } for (auto b: i.second) @@ -583,7 +590,7 @@ bytes Assembly::assemble() const } for (unsigned pos: sizeRef) { - bytesRef r(ret.data() + pos, bytesPerTag); + bytesRef r(ret.data() + pos, bytesPerDataRef); toBigEndian(ret.size(), r); } return ret; From 857dca6c8d4b9c35c7cb5229906c0ecf9004a069 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 18 Dec 2014 09:06:06 +0100 Subject: [PATCH 248/277] refund tests --- test/stRefundTestFiller.json | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 test/stRefundTestFiller.json diff --git a/test/stRefundTestFiller.json b/test/stRefundTestFiller.json new file mode 100644 index 000000000..3745c8d81 --- /dev/null +++ b/test/stRefundTestFiller.json @@ -0,0 +1,37 @@ +{ + "refund0" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 1 ]] 0 }", + "storage" : { + "0x01" : "0x01" + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "850", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + } +} From 87721356e1e5c44375db9331034312152c8f4f36 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 18 Dec 2014 09:06:51 +0100 Subject: [PATCH 249/277] refund test inclusion --- test/state.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/state.cpp b/test/state.cpp index f183c4813..5bdfb419b 100644 --- a/test/state.cpp +++ b/test/state.cpp @@ -140,11 +140,22 @@ BOOST_AUTO_TEST_CASE(stInitCodeTest) dev::test::executeTests("stInitCodeTest", "/StateTests", dev::test::doStateTests); } +BOOST_AUTO_TEST_CASE(stTransactionTest) +{ + dev::test::executeTests("stTransactionTest", "/StateTests", dev::test::doStateTests); +} + BOOST_AUTO_TEST_CASE(stSpecialTest) { dev::test::executeTests("stSpecialTest", "/StateTests", dev::test::doStateTests); } +BOOST_AUTO_TEST_CASE(stRefundTest) +{ + dev::test::executeTests("stRefundTest", "/StateTests", dev::test::doStateTests); +} + + BOOST_AUTO_TEST_CASE(stCreateTest) { for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) From 0bf7eb0670101fc2ba74e6ae276299e7bc197579 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 18 Dec 2014 09:32:24 +0100 Subject: [PATCH 250/277] more refund tests --- test/stRefundTestFiller.json | 112 ++++++++++++++++++++++++++++++++++- 1 file changed, 110 insertions(+), 2 deletions(-) diff --git a/test/stRefundTestFiller.json b/test/stRefundTestFiller.json index 3745c8d81..4060bbb72 100644 --- a/test/stRefundTestFiller.json +++ b/test/stRefundTestFiller.json @@ -1,5 +1,5 @@ { - "refund0" : { + "refund_getEtherBack" : { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -33,5 +33,113 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - } + }, + + "refund_changeNonZeroStorage" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 1 ]] 23 }", + "storage" : { + "0x01" : "0x01" + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "850", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "refund_OOG" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 1 ]] 0 }", + "storage" : { + "0x01" : "0x01" + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "500", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "500", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "refund_NoOOG_1" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 1 ]] 0 }", + "storage" : { + "0x01" : "0x01" + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "502", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "502", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + } } From 23c46dd468f087881c89ee85ca1567f60d57ea5f Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 18 Dec 2014 09:50:45 +0100 Subject: [PATCH 251/277] style --- test/state.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/test/state.cpp b/test/state.cpp index 5bdfb419b..d8a3dd283 100644 --- a/test/state.cpp +++ b/test/state.cpp @@ -155,7 +155,6 @@ BOOST_AUTO_TEST_CASE(stRefundTest) dev::test::executeTests("stRefundTest", "/StateTests", dev::test::doStateTests); } - BOOST_AUTO_TEST_CASE(stCreateTest) { for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) From 80368b870b55eac441e43a12b558361f04a5c1e6 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 17 Dec 2014 17:47:34 +0100 Subject: [PATCH 252/277] windows icon --- CMakeLists.txt | 4 ++++ alethzero/alethzero.ico | Bin 0 -> 370070 bytes 2 files changed, 4 insertions(+) create mode 100644 alethzero/alethzero.ico diff --git a/CMakeLists.txt b/CMakeLists.txt index 1293b4427..5763c9b85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -165,6 +165,8 @@ if (WIN32) set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") set(CPACK_PACKAGE_VERSION "0.7") set(CPACK_GENERATOR "NSIS") + # seems to be not working + # set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/alethzero/alethzero.bmp") # our stuff set(CPACK_COMPONENT_ALETHZERO_GROUP "Applications") @@ -178,6 +180,8 @@ if (WIN32) set(CPACK_NSIS_URL_INFO_ABOUT "https://github.com/ethereum/cpp-ethereum") set(CPACK_NSIS_CONTACT "ethereum.org") set(CPACK_NSIS_MODIFY_PATH ON) + set(CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}/alethzero/alethzero.ico") + set(CPACK_NSIS_MUI_UNIICON "${CMAKE_CURRENT_SOURCE_DIR}/alethzero/alethzero.ico") include(CPack) endif (WIN32) diff --git a/alethzero/alethzero.ico b/alethzero/alethzero.ico new file mode 100644 index 0000000000000000000000000000000000000000..acee27751646c7054bd617e0be34ed1c4e55a1f3 GIT binary patch literal 370070 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 Date: Thu, 18 Dec 2014 14:39:16 +0100 Subject: [PATCH 253/277] Possibility to replace source and obtain ContractDefinition by name. --- libsolidity/CompilerStack.cpp | 12 ++++++++---- libsolidity/CompilerStack.h | 9 +++++++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/libsolidity/CompilerStack.cpp b/libsolidity/CompilerStack.cpp index 9fdc88baa..79716fdec 100644 --- a/libsolidity/CompilerStack.cpp +++ b/libsolidity/CompilerStack.cpp @@ -36,13 +36,12 @@ namespace dev namespace solidity { -void CompilerStack::addSource(string const& _name, string const& _content) +bool CompilerStack::addSource(string const& _name, string const& _content) { - if (m_sources.count(_name)) - BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Source by given name already exists.")); - + bool existed = m_sources.count(_name); reset(true); m_sources[_name].scanner = make_shared(CharStream(_content), _name); + return existed; } void CompilerStack::setSource(string const& _sourceCode) @@ -181,6 +180,11 @@ SourceUnit const& CompilerStack::getAST(string const& _sourceName) const return *getSource(_sourceName).ast; } +ContractDefinition const& CompilerStack::getContractDefinition(string const& _contractName) const +{ + return *getContract(_contractName).contract; +} + bytes CompilerStack::staticCompile(std::string const& _sourceCode, bool _optimize) { CompilerStack stack; diff --git a/libsolidity/CompilerStack.h b/libsolidity/CompilerStack.h index 5ad6f0a60..358c8fb77 100644 --- a/libsolidity/CompilerStack.h +++ b/libsolidity/CompilerStack.h @@ -57,7 +57,8 @@ public: CompilerStack(): m_parseSuccessful(false) {} /// Adds a source object (e.g. file) to the parser. After this, parse has to be called again. - void addSource(std::string const& _name, std::string const& _content); + /// @returns true if a source object by the name already existed and was replaced. + bool addSource(std::string const& _name, std::string const& _content); void setSource(std::string const& _sourceCode); /// Parses all source units that were added void parse(); @@ -86,9 +87,13 @@ public: /// Can be one of 3 types defined at @c DocumentationType std::string const& getJsonDocumentation(std::string const& _contractName, DocumentationType _type) const; - /// Returns the previously used scanner, useful for counting lines during error reporting. + /// @returns the previously used scanner, useful for counting lines during error reporting. Scanner const& getScanner(std::string const& _sourceName = "") const; + /// @returns the parsed source unit with the supplied name. SourceUnit const& getAST(std::string const& _sourceName = "") const; + /// @returns the parsed contract with the supplied name. Throws an exception if the contract + /// does not exist. + ContractDefinition const& getContractDefinition(std::string const& _contractName) const; /// Compile the given @a _sourceCode to bytecode. If a scanner is provided, it is used for /// scanning the source code - this is useful for printing exception information. From d19d4b29db7b6e958b473ab29278bc5ad700d9ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Thu, 18 Dec 2014 15:03:34 +0100 Subject: [PATCH 254/277] Update evmjit submodule: object cache speeds up recursive calls --- evmjit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evmjit b/evmjit index b37ce8e97..8287c6040 160000 --- a/evmjit +++ b/evmjit @@ -1 +1 @@ -Subproject commit b37ce8e9727683b8c7afb84520f42a908318f8d8 +Subproject commit 8287c6040a4900cb8b091ffbe284c7f478c60c49 From 6d48f3e98764fff270397fc00d37f9c6328294fd Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Wed, 17 Dec 2014 18:53:18 +0100 Subject: [PATCH 255/277] Work in progress for /** ... */ natspec comments - Work in progress on the scanner for recognizing the second type of doxygen comments for Natspec. --- libsolidity/Scanner.cpp | 58 +++++++++++++++++++++++++++++++++++++--- libsolidity/Scanner.h | 3 ++- test/solidityScanner.cpp | 7 +++++ 3 files changed, 63 insertions(+), 5 deletions(-) diff --git a/libsolidity/Scanner.cpp b/libsolidity/Scanner.cpp index 1a21149a1..2e9b7b454 100644 --- a/libsolidity/Scanner.cpp +++ b/libsolidity/Scanner.cpp @@ -219,7 +219,7 @@ Token::Value Scanner::skipSingleLineComment() return Token::WHITESPACE; } -Token::Value Scanner::scanDocumentationComment() +Token::Value Scanner::scanSingleLineDocComment() { LiteralScope literal(this, LITERAL_TYPE_COMMENT); advance(); //consume the last '/' @@ -250,7 +250,6 @@ Token::Value Scanner::scanDocumentationComment() Token::Value Scanner::skipMultiLineComment() { - solAssert(m_char == '*', ""); advance(); while (!isSourcePastEndOfInput()) { @@ -270,6 +269,43 @@ Token::Value Scanner::skipMultiLineComment() return Token::ILLEGAL; } +Token::Value Scanner::scanMultiLineDocComment() +{ + LiteralScope literal(this, LITERAL_TYPE_COMMENT); + bool endFound = false; + + advance(); //consume the last '*' + while (!isSourcePastEndOfInput()) + { + // skip starting '*' in multiine comments + if (isLineTerminator(m_char)) + { + skipWhitespace(); + if (!m_source.isPastEndOfInput(2) && m_source.get(1) == '*' && m_source.get(2) != '/') + { + addCommentLiteralChar('\n'); + m_char = m_source.advanceAndGet(3); + } + else + addCommentLiteralChar('\n'); + } + + if (!m_source.isPastEndOfInput(1) && m_source.get(0) == '*' && m_source.get(1) == '/') + { + m_source.advanceAndGet(2); + endFound = true; + break; + } + addCommentLiteralChar(m_char); + advance(); + } + literal.complete(); + if (!endFound) + return Token::ILLEGAL; + else + return Token::COMMENT_LITERAL; +} + void Scanner::scanToken() { m_nextToken.literal.clear(); @@ -381,7 +417,7 @@ void Scanner::scanToken() { Token::Value comment; m_nextSkippedComment.location.start = getSourcePos(); - comment = scanDocumentationComment(); + comment = scanSingleLineDocComment(); m_nextSkippedComment.location.end = getSourcePos(); m_nextSkippedComment.token = comment; token = Token::WHITESPACE; @@ -390,7 +426,21 @@ void Scanner::scanToken() token = skipSingleLineComment(); } else if (m_char == '*') - token = skipMultiLineComment(); + { + if (!advance()) /* slash star comment before EOS */ + token = Token::WHITESPACE; + else if (m_char == '*') + { + Token::Value comment; + m_nextSkippedComment.location.start = getSourcePos(); + comment = scanMultiLineDocComment(); + m_nextSkippedComment.location.end = getSourcePos(); + m_nextSkippedComment.token = comment; + token = Token::WHITESPACE; + } + else + token = skipMultiLineComment(); + } else if (m_char == '=') token = selectToken(Token::ASSIGN_DIV); else diff --git a/libsolidity/Scanner.h b/libsolidity/Scanner.h index 18b1f5d3a..7f1b18352 100644 --- a/libsolidity/Scanner.h +++ b/libsolidity/Scanner.h @@ -190,7 +190,8 @@ private: Token::Value scanIdentifierOrKeyword(); Token::Value scanString(); - Token::Value scanDocumentationComment(); + Token::Value scanSingleLineDocComment(); + Token::Value scanMultiLineDocComment(); /// Scans an escape-sequence which is part of a string and adds the /// decoded character to the current literal. Returns true if a pattern diff --git a/test/solidityScanner.cpp b/test/solidityScanner.cpp index 573affe6d..2b8c7c458 100644 --- a/test/solidityScanner.cpp +++ b/test/solidityScanner.cpp @@ -160,6 +160,13 @@ BOOST_AUTO_TEST_CASE(documentation_comments_parsed_begin) BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), " Send $(value / 1000) chocolates to the user"); } +BOOST_AUTO_TEST_CASE(multiline_documentation_comments_parsed_begin) +{ + Scanner scanner(CharStream("/** Send $(value / 1000) chocolates to the user*/")); + BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::EOS); + BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), " Send $(value / 1000) chocolates to the user"); +} + BOOST_AUTO_TEST_CASE(documentation_comments_parsed) { Scanner scanner(CharStream("some other tokens /// Send $(value / 1000) chocolates to the user")); From 61a1f4436c5561a6c521b9c6009c57c76d275adb Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Thu, 18 Dec 2014 13:27:25 +0100 Subject: [PATCH 256/277] Scanner properly scans multiline natspec comments - Single and multiline natspect comments get the initial whitespace skipped now - Some rules introduced for the multiline comments. If first line is empty then no newline is added to the literal. Same thing with the last line. Finally in all lines initial '*' are skipped --- libsolidity/Scanner.cpp | 36 ++++++++++++++++++++++++++++-------- libsolidity/Scanner.h | 2 ++ test/solidityScanner.cpp | 25 ++++++++++++++++++++++--- 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/libsolidity/Scanner.cpp b/libsolidity/Scanner.cpp index 2e9b7b454..890d69494 100644 --- a/libsolidity/Scanner.cpp +++ b/libsolidity/Scanner.cpp @@ -209,6 +209,15 @@ bool Scanner::skipWhitespace() return getSourcePos() != startPosition; } +bool Scanner::skipWhitespaceExceptLF() +{ + int const startPosition = getSourcePos(); + while (m_char == ' ' || m_char == '\t') + advance(); + // Return whether or not we skipped any characters. + return getSourcePos() != startPosition; +} + Token::Value Scanner::skipSingleLineComment() { // The line terminator at the end of the line is not considered @@ -222,7 +231,8 @@ Token::Value Scanner::skipSingleLineComment() Token::Value Scanner::scanSingleLineDocComment() { LiteralScope literal(this, LITERAL_TYPE_COMMENT); - advance(); //consume the last '/' + advance(); //consume the last '/' at /// + skipWhitespaceExceptLF(); while (!isSourcePastEndOfInput()) { if (isLineTerminator(m_char)) @@ -273,18 +283,27 @@ Token::Value Scanner::scanMultiLineDocComment() { LiteralScope literal(this, LITERAL_TYPE_COMMENT); bool endFound = false; + bool charsAdded = false; - advance(); //consume the last '*' + advance(); //consume the last '*' at /** + skipWhitespaceExceptLF(); while (!isSourcePastEndOfInput()) { - // skip starting '*' in multiine comments + //handle newlines in multline comments if (isLineTerminator(m_char)) { skipWhitespace(); - if (!m_source.isPastEndOfInput(2) && m_source.get(1) == '*' && m_source.get(2) != '/') - { - addCommentLiteralChar('\n'); - m_char = m_source.advanceAndGet(3); + if (!m_source.isPastEndOfInput(1) && m_source.get(0) == '*' && m_source.get(1) != '/') + { // skip first '*' in subsequent lines + if (charsAdded) + addCommentLiteralChar('\n'); + m_char = m_source.advanceAndGet(2); + } + else if (!m_source.isPastEndOfInput(1) && m_source.get(0) == '*' && m_source.get(1) == '/') + { // if after newline the comment ends, don't insert the newline + m_char = m_source.advanceAndGet(2); + endFound = true; + break; } else addCommentLiteralChar('\n'); @@ -292,11 +311,12 @@ Token::Value Scanner::scanMultiLineDocComment() if (!m_source.isPastEndOfInput(1) && m_source.get(0) == '*' && m_source.get(1) == '/') { - m_source.advanceAndGet(2); + m_char = m_source.advanceAndGet(2); endFound = true; break; } addCommentLiteralChar(m_char); + charsAdded = true; advance(); } literal.complete(); diff --git a/libsolidity/Scanner.h b/libsolidity/Scanner.h index 7f1b18352..5e70db51d 100644 --- a/libsolidity/Scanner.h +++ b/libsolidity/Scanner.h @@ -182,6 +182,8 @@ private: /// Skips all whitespace and @returns true if something was skipped. bool skipWhitespace(); + /// Skips all whitespace except Line feeds and returns true if something was skipped + bool skipWhitespaceExceptLF(); Token::Value skipSingleLineComment(); Token::Value skipMultiLineComment(); diff --git a/test/solidityScanner.cpp b/test/solidityScanner.cpp index 2b8c7c458..159e53055 100644 --- a/test/solidityScanner.cpp +++ b/test/solidityScanner.cpp @@ -157,14 +157,14 @@ BOOST_AUTO_TEST_CASE(documentation_comments_parsed_begin) { Scanner scanner(CharStream("/// Send $(value / 1000) chocolates to the user")); BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::EOS); - BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), " Send $(value / 1000) chocolates to the user"); + BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), "Send $(value / 1000) chocolates to the user"); } BOOST_AUTO_TEST_CASE(multiline_documentation_comments_parsed_begin) { Scanner scanner(CharStream("/** Send $(value / 1000) chocolates to the user*/")); BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::EOS); - BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), " Send $(value / 1000) chocolates to the user"); + BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), "Send $(value / 1000) chocolates to the user"); } BOOST_AUTO_TEST_CASE(documentation_comments_parsed) @@ -174,7 +174,19 @@ BOOST_AUTO_TEST_CASE(documentation_comments_parsed) BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER); BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER); BOOST_CHECK_EQUAL(scanner.next(), Token::EOS); - BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), " Send $(value / 1000) chocolates to the user"); + BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), "Send $(value / 1000) chocolates to the user"); +} + +BOOST_AUTO_TEST_CASE(multiline_documentation_comments_parsed) +{ + Scanner scanner(CharStream("some other tokens /**\n" + "* Send $(value / 1000) chocolates to the user\n" + "*/")); + BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::IDENTIFIER); + BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER); + BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER); + BOOST_CHECK_EQUAL(scanner.next(), Token::EOS); + BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), "Send $(value / 1000) chocolates to the user"); } BOOST_AUTO_TEST_CASE(comment_before_eos) @@ -191,6 +203,13 @@ BOOST_AUTO_TEST_CASE(documentation_comment_before_eos) BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), ""); } +BOOST_AUTO_TEST_CASE(empty_multiline_documentation_comment_before_eos) +{ + Scanner scanner(CharStream("/***/")); + BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::EOS); + BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), ""); +} + BOOST_AUTO_TEST_CASE(comments_mixed_in_sequence) { Scanner scanner(CharStream("hello_world ///documentation comment \n" From 30beaca35955476ef07ee1f9c82735b0d63241bf Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Thu, 18 Dec 2014 14:43:35 +0100 Subject: [PATCH 257/277] Changes in InterfaceHandler to deal with multiline natspec - Also now Solidity scanner considers Carriage Return as whitespace - Tests for Natspec generation with the new multiline comments --- libsolidity/InterfaceHandler.cpp | 46 +++++++++++++------------------- libsolidity/InterfaceHandler.h | 3 ++- libsolidity/Scanner.cpp | 2 +- test/solidityNatspecJSON.cpp | 29 ++++++++++++++++++++ 4 files changed, 51 insertions(+), 29 deletions(-) diff --git a/libsolidity/InterfaceHandler.cpp b/libsolidity/InterfaceHandler.cpp index c734fa38c..9ae284b40 100644 --- a/libsolidity/InterfaceHandler.cpp +++ b/libsolidity/InterfaceHandler.cpp @@ -166,9 +166,12 @@ static inline std::string::const_iterator skipLineOrEOS(std::string::const_itera std::string::const_iterator InterfaceHandler::parseDocTagLine(std::string::const_iterator _pos, std::string::const_iterator _end, std::string& _tagString, - DocTagType _tagType) + DocTagType _tagType, + bool _appending) { auto nlPos = std::find(_pos, _end, '\n'); + if (_appending && *_pos != ' ') + _tagString += " "; std::copy(_pos, nlPos, back_inserter(_tagString)); m_lastTag = _tagType; return skipLineOrEOS(nlPos, _end); @@ -201,7 +204,8 @@ std::string::const_iterator InterfaceHandler::appendDocTagParam(std::string::con solAssert(!m_params.empty(), "Internal: Tried to append to empty parameter"); auto pair = m_params.back(); - pair.second += " "; + if (*_pos != ' ') + pair.second += " "; auto nlPos = std::find(_pos, _end, '\n'); std::copy(_pos, nlPos, back_inserter(pair.second)); @@ -221,17 +225,17 @@ std::string::const_iterator InterfaceHandler::parseDocTag(std::string::const_ite if (m_lastTag == DocTagType::NONE || _tag != "") { if (_tag == "dev") - return parseDocTagLine(_pos, _end, m_dev, DocTagType::DEV); + return parseDocTagLine(_pos, _end, m_dev, DocTagType::DEV, false); else if (_tag == "notice") - return parseDocTagLine(_pos, _end, m_notice, DocTagType::NOTICE); + return parseDocTagLine(_pos, _end, m_notice, DocTagType::NOTICE, false); else if (_tag == "return") - return parseDocTagLine(_pos, _end, m_return, DocTagType::RETURN); + return parseDocTagLine(_pos, _end, m_return, DocTagType::RETURN, false); else if (_tag == "author") { if (_owner == CommentOwner::CONTRACT) - return parseDocTagLine(_pos, _end, m_contractAuthor, DocTagType::AUTHOR); + return parseDocTagLine(_pos, _end, m_contractAuthor, DocTagType::AUTHOR, false); else if (_owner == CommentOwner::FUNCTION) - return parseDocTagLine(_pos, _end, m_author, DocTagType::AUTHOR); + return parseDocTagLine(_pos, _end, m_author, DocTagType::AUTHOR, false); else // LTODO: for now this else makes no sense but later comments will go to more language constructs BOOST_THROW_EXCEPTION(DocstringParsingError() << errinfo_comment("@author tag is legal only for contracts")); @@ -239,7 +243,7 @@ std::string::const_iterator InterfaceHandler::parseDocTag(std::string::const_ite else if (_tag == "title") { if (_owner == CommentOwner::CONTRACT) - return parseDocTagLine(_pos, _end, m_title, DocTagType::TITLE); + return parseDocTagLine(_pos, _end, m_title, DocTagType::TITLE, false); else // LTODO: Unknown tag, throw some form of warning and not just an exception BOOST_THROW_EXCEPTION(DocstringParsingError() << errinfo_comment("@title tag is legal only for contracts")); @@ -261,34 +265,22 @@ std::string::const_iterator InterfaceHandler::appendDocTag(std::string::const_it switch (m_lastTag) { case DocTagType::DEV: - m_dev += " "; - return parseDocTagLine(_pos, _end, m_dev, DocTagType::DEV); + return parseDocTagLine(_pos, _end, m_dev, DocTagType::DEV, true); case DocTagType::NOTICE: - m_notice += " "; - return parseDocTagLine(_pos, _end, m_notice, DocTagType::NOTICE); + return parseDocTagLine(_pos, _end, m_notice, DocTagType::NOTICE, true); case DocTagType::RETURN: - m_return += " "; - return parseDocTagLine(_pos, _end, m_return, DocTagType::RETURN); + return parseDocTagLine(_pos, _end, m_return, DocTagType::RETURN, true); case DocTagType::AUTHOR: if (_owner == CommentOwner::CONTRACT) - { - m_contractAuthor += " "; - return parseDocTagLine(_pos, _end, m_contractAuthor, DocTagType::AUTHOR); - } + return parseDocTagLine(_pos, _end, m_contractAuthor, DocTagType::AUTHOR, true); else if (_owner == CommentOwner::FUNCTION) - { - m_author += " "; - return parseDocTagLine(_pos, _end, m_author, DocTagType::AUTHOR); - } + return parseDocTagLine(_pos, _end, m_author, DocTagType::AUTHOR, true); else // LTODO: Unknown tag, throw some form of warning and not just an exception BOOST_THROW_EXCEPTION(DocstringParsingError() << errinfo_comment("@author tag in illegal comment")); case DocTagType::TITLE: if (_owner == CommentOwner::CONTRACT) - { - m_title += " "; - return parseDocTagLine(_pos, _end, m_title, DocTagType::TITLE); - } + return parseDocTagLine(_pos, _end, m_title, DocTagType::TITLE, true); else // LTODO: Unknown tag, throw some form of warning and not just an exception BOOST_THROW_EXCEPTION(DocstringParsingError() << errinfo_comment("@title tag in illegal comment")); @@ -329,7 +321,7 @@ void InterfaceHandler::parseDocString(std::string const& _string, CommentOwner _ currPos = parseDocTag(tagNameEndPos + 1, end, std::string(tagPos + 1, tagNameEndPos), _owner); } else if (m_lastTag != DocTagType::NONE) // continuation of the previous tag - currPos = appendDocTag(currPos + 1, end, _owner); + currPos = appendDocTag(currPos, end, _owner); else if (currPos != end) // skip the line if a newline was found currPos = nlPos + 1; } diff --git a/libsolidity/InterfaceHandler.h b/libsolidity/InterfaceHandler.h index d271a6697..c8399d71f 100644 --- a/libsolidity/InterfaceHandler.h +++ b/libsolidity/InterfaceHandler.h @@ -92,7 +92,8 @@ private: std::string::const_iterator parseDocTagLine(std::string::const_iterator _pos, std::string::const_iterator _end, std::string& _tagString, - DocTagType _tagType); + DocTagType _tagType, + bool _appending); std::string::const_iterator parseDocTagParam(std::string::const_iterator _pos, std::string::const_iterator _end); std::string::const_iterator appendDocTagParam(std::string::const_iterator _pos, diff --git a/libsolidity/Scanner.cpp b/libsolidity/Scanner.cpp index 890d69494..69b61ce4b 100644 --- a/libsolidity/Scanner.cpp +++ b/libsolidity/Scanner.cpp @@ -80,7 +80,7 @@ bool isLineTerminator(char c) } bool isWhiteSpace(char c) { - return c == ' ' || c == '\n' || c == '\t'; + return c == ' ' || c == '\n' || c == '\t' || c == '\r'; } bool isIdentifierStart(char c) { diff --git a/test/solidityNatspecJSON.cpp b/test/solidityNatspecJSON.cpp index 2c3ded08d..5b48a67ce 100644 --- a/test/solidityNatspecJSON.cpp +++ b/test/solidityNatspecJSON.cpp @@ -394,6 +394,35 @@ BOOST_AUTO_TEST_CASE(dev_multiline_return) checkNatspec(sourceCode, natspec, false); } +BOOST_AUTO_TEST_CASE(dev_multiline_comment) +{ + char const* sourceCode = "contract test {\n" + " /**\n" + " * @dev Multiplies a number by 7 and adds second parameter\n" + " * @param a Documentation for the first parameter starts here.\n" + " * Since it's a really complicated parameter we need 2 lines\n" + " * @param second Documentation for the second parameter\n" + " * @return The result of the multiplication\n" + " * and cookies with nutella\n" + " */" + " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" + "}\n"; + + char const* natspec = "{" + "\"methods\":{" + " \"mul\":{ \n" + " \"details\": \"Multiplies a number by 7 and adds second parameter\",\n" + " \"params\": {\n" + " \"a\": \"Documentation for the first parameter starts here. Since it's a really complicated parameter we need 2 lines\",\n" + " \"second\": \"Documentation for the second parameter\"\n" + " },\n" + " \"return\": \"The result of the multiplication and cookies with nutella\"\n" + " }\n" + "}}"; + + checkNatspec(sourceCode, natspec, false); +} + BOOST_AUTO_TEST_CASE(dev_contract_no_doc) { char const* sourceCode = "contract test {\n" From 8edb5b8b54f1c023f68688f6ac52d9878975b8a7 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Thu, 18 Dec 2014 15:21:03 +0100 Subject: [PATCH 258/277] Solidity Tests names are now more consistent - File names and Boost Test Suite have the same name now for every solidity Test, so that there is no need to guess or check when you want to run a specific suite from the command line --- test/{solidityJSONInterfaceTest.cpp => SolidityABIJSON.cpp} | 0 test/{solidityCompiler.cpp => SolidityCompiler.cpp} | 0 test/{solidityEndToEndTest.cpp => SolidityEndToEndTest.cpp} | 2 +- ...ityExpressionCompiler.cpp => SolidityExpressionCompiler.cpp} | 0 ...eAndTypeResolution.cpp => SolidityNameAndTypeResolution.cpp} | 0 test/{solidityNatspecJSON.cpp => SolidityNatspecJSON.cpp} | 0 test/{solidityOptimizerTest.cpp => SolidityOptimizer.cpp} | 2 +- test/{solidityParser.cpp => SolidityParser.cpp} | 0 test/{solidityScanner.cpp => SolidityScanner.cpp} | 0 9 files changed, 2 insertions(+), 2 deletions(-) rename test/{solidityJSONInterfaceTest.cpp => SolidityABIJSON.cpp} (100%) rename test/{solidityCompiler.cpp => SolidityCompiler.cpp} (100%) rename test/{solidityEndToEndTest.cpp => SolidityEndToEndTest.cpp} (99%) rename test/{solidityExpressionCompiler.cpp => SolidityExpressionCompiler.cpp} (100%) rename test/{solidityNameAndTypeResolution.cpp => SolidityNameAndTypeResolution.cpp} (100%) rename test/{solidityNatspecJSON.cpp => SolidityNatspecJSON.cpp} (100%) rename test/{solidityOptimizerTest.cpp => SolidityOptimizer.cpp} (98%) rename test/{solidityParser.cpp => SolidityParser.cpp} (100%) rename test/{solidityScanner.cpp => SolidityScanner.cpp} (100%) diff --git a/test/solidityJSONInterfaceTest.cpp b/test/SolidityABIJSON.cpp similarity index 100% rename from test/solidityJSONInterfaceTest.cpp rename to test/SolidityABIJSON.cpp diff --git a/test/solidityCompiler.cpp b/test/SolidityCompiler.cpp similarity index 100% rename from test/solidityCompiler.cpp rename to test/SolidityCompiler.cpp diff --git a/test/solidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp similarity index 99% rename from test/solidityEndToEndTest.cpp rename to test/SolidityEndToEndTest.cpp index 26f5528ab..aa74f8186 100644 --- a/test/solidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -36,7 +36,7 @@ namespace solidity namespace test { -BOOST_FIXTURE_TEST_SUITE(SolidityCompilerEndToEndTest, ExecutionFramework) +BOOST_FIXTURE_TEST_SUITE(SolidityEndToEndTest, ExecutionFramework) BOOST_AUTO_TEST_CASE(smoke_test) { diff --git a/test/solidityExpressionCompiler.cpp b/test/SolidityExpressionCompiler.cpp similarity index 100% rename from test/solidityExpressionCompiler.cpp rename to test/SolidityExpressionCompiler.cpp diff --git a/test/solidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp similarity index 100% rename from test/solidityNameAndTypeResolution.cpp rename to test/SolidityNameAndTypeResolution.cpp diff --git a/test/solidityNatspecJSON.cpp b/test/SolidityNatspecJSON.cpp similarity index 100% rename from test/solidityNatspecJSON.cpp rename to test/SolidityNatspecJSON.cpp diff --git a/test/solidityOptimizerTest.cpp b/test/SolidityOptimizer.cpp similarity index 98% rename from test/solidityOptimizerTest.cpp rename to test/SolidityOptimizer.cpp index 388e0579c..ef5c6f9b5 100644 --- a/test/solidityOptimizerTest.cpp +++ b/test/SolidityOptimizer.cpp @@ -71,7 +71,7 @@ protected: Address m_nonOptimizedContract; }; -BOOST_FIXTURE_TEST_SUITE(SolidityOptimizerTest, OptimizerTestFramework) +BOOST_FIXTURE_TEST_SUITE(SolidityOptimizer, OptimizerTestFramework) BOOST_AUTO_TEST_CASE(smoke_test) { diff --git a/test/solidityParser.cpp b/test/SolidityParser.cpp similarity index 100% rename from test/solidityParser.cpp rename to test/SolidityParser.cpp diff --git a/test/solidityScanner.cpp b/test/SolidityScanner.cpp similarity index 100% rename from test/solidityScanner.cpp rename to test/SolidityScanner.cpp From 2e3d45004681407393f0742bec6d9ed463211dcf Mon Sep 17 00:00:00 2001 From: ethdev Date: Thu, 18 Dec 2014 15:39:15 +0100 Subject: [PATCH 259/277] copy qml dependencies of mix to install directory --- cmake/EthExecutableHelper.cmake | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/cmake/EthExecutableHelper.cmake b/cmake/EthExecutableHelper.cmake index 0ec1e10d4..5f4ae3c09 100644 --- a/cmake/EthExecutableHelper.cmake +++ b/cmake/EthExecutableHelper.cmake @@ -60,7 +60,11 @@ macro(eth_install_executable EXECUTABLE) cmake_parse_arguments (ETH_INSTALL_EXECUTABLE "${options}" "${one_value_args}" "${multi_value_args}" "${extra_macro_args}") if (ETH_INSTALL_EXECUTABLE_QMLDIR) - set(eth_qml_dir "-qmldir=${ETH_INSTALL_EXECUTABLE_QMLDIR}") + if (APPLE) + set(eth_qml_dir "-qmldir=${ETH_INSTALL_EXECUTABLE_QMLDIR}") + elseif (WIN32) + set(eth_qml_dir --qmldir ${ETH_INSTALL_EXECUTABLE_QMLDIR}) + endif() message(STATUS "${EXECUTABLE} qmldir: ${eth_qml_dir}") endif() @@ -68,7 +72,8 @@ macro(eth_install_executable EXECUTABLE) # First have qt5 install plugins and frameworks add_custom_command(TARGET ${EXECUTABLE} POST_BUILD COMMAND ${MACDEPLOYQT_APP} ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app ${eth_qml_dir} - WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) + WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + ) # This tool and next will inspect linked libraries in order to determine which dependencies are required if (${CMAKE_CFG_INTDIR} STREQUAL ".") @@ -108,6 +113,13 @@ macro(eth_install_executable EXECUTABLE) $/platforms ) + # ugly way, improve that + add_custom_command(TARGET ${EXECUTABLE} POST_BUILD + COMMAND cmake -E copy_directory + "${ETH_DEPENDENCY_INSTALL_DIR}/qml" + $ + ) + install( FILES ${DLLS} DESTINATION bin COMPONENT ${EXECUTABLE} @@ -118,6 +130,14 @@ macro(eth_install_executable EXECUTABLE) COMPONENT ${EXECUTABLE} ) + file (GLOB QMLS ${ETH_DEPENDENCY_INSTALL_DIR}/qml/*) + foreach(QML ${QMLS}) + install( DIRECTORY ${QML} + DESTINATION bin + COMPONENT ${EXECUTABLE} + ) + endforeach() + install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin COMPONENT ${EXECUTABLE} From 23d4f98b744887bdc1f1952bf303651ac6573e3e Mon Sep 17 00:00:00 2001 From: ethdev Date: Thu, 18 Dec 2014 15:50:23 +0100 Subject: [PATCH 260/277] alethzero.exe icon --- alethzero/CMakeLists.txt | 1 + alethzero/alethzero.rc | 1 + cmake/EthExecutableHelper.cmake | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 alethzero/alethzero.rc diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index 39c02d6be..8c8a37a42 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -27,6 +27,7 @@ endif () eth_add_executable(${EXECUTABLE} ICON alethzero UI_RESOURCES alethzero.icns Main.ui + WIN_RESOURCES alethzero.rc ) add_dependencies(${EXECUTABLE} BuildInfo.h) diff --git a/alethzero/alethzero.rc b/alethzero/alethzero.rc new file mode 100644 index 000000000..29c778bd4 --- /dev/null +++ b/alethzero/alethzero.rc @@ -0,0 +1 @@ +APP_ICON ICON DISCARDABLE "alethzero.ico" \ No newline at end of file diff --git a/cmake/EthExecutableHelper.cmake b/cmake/EthExecutableHelper.cmake index 5f4ae3c09..88e2a3e16 100644 --- a/cmake/EthExecutableHelper.cmake +++ b/cmake/EthExecutableHelper.cmake @@ -18,7 +18,7 @@ macro(eth_add_executable EXECUTABLE) set (extra_macro_args ${ARGN}) set (options) set (one_value_args ICON) - set (multi_value_args UI_RESOURCES) + set (multi_value_args UI_RESOURCES WIN_RESOURCES) cmake_parse_arguments (ETH_ADD_EXECUTABLE "${options}" "${one_value_args}" "${multi_value_args}" "${extra_macro_args}") if (APPLE) @@ -38,7 +38,7 @@ macro(eth_add_executable EXECUTABLE) set_source_files_properties(${MACOSX_BUNDLE_ICON_FILE}.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources) else () - add_executable(${EXECUTABLE} ${ETH_ADD_EXECUTABLE_UI_RESOURCES} ${SRC_LIST} ${HEADERS}) + add_executable(${EXECUTABLE} ${ETH_ADD_EXECUTABLE_UI_RESOURCES} ${ETH_ADD_EXECUTABLE_WIN_RESOURCES} ${SRC_LIST} ${HEADERS}) endif() endmacro() From b657b009ef7a272d105f92fbc0d3d6e449664fd3 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 18 Dec 2014 16:03:59 +0100 Subject: [PATCH 261/277] Cleanups and YP formalism. --- libethereum/Transaction.cpp | 4 ++-- libevm/VM.h | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/libethereum/Transaction.cpp b/libethereum/Transaction.cpp index 0c1173134..24c56930e 100644 --- a/libethereum/Transaction.cpp +++ b/libethereum/Transaction.cpp @@ -43,9 +43,9 @@ Transaction::Transaction(bytesConstRef _rlpData, bool _checkSender) m_receiveAddress = rlp[field = 3].toHash
(); m_value = rlp[field = 4].toInt(); m_data = rlp[field = 5].toBytes(); + byte v = rlp[field = 6].toInt() - 27; h256 r = rlp[field = 7].toInt(); h256 s = rlp[field = 8].toInt(); - byte v = rlp[field = 6].toInt() - 27; m_vrs = SignatureStruct{ r, s, v }; if (_checkSender) m_sender = sender(); @@ -74,7 +74,7 @@ Address Transaction::sender() const { if (!m_sender) { - auto p = recover(*(Signature const*)&m_vrs, sha3(WithoutSignature)); + auto p = recover(m_vrs, sha3(WithoutSignature)); if (!p) BOOST_THROW_EXCEPTION(InvalidSignature()); m_sender = right160(dev::sha3(bytesConstRef(p.data(), sizeof(p)))); diff --git a/libevm/VM.h b/libevm/VM.h index 3eb330fcd..1f3fc17d5 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -217,6 +217,8 @@ inline bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _st require(7); runGas = (bigint)c_callGas + m_stack[m_stack.size() - 1]; newTempSize = std::max(memNeed(m_stack[m_stack.size() - 6], m_stack[m_stack.size() - 7]), memNeed(m_stack[m_stack.size() - 4], m_stack[m_stack.size() - 5])); + if (_ext.depth == 1024) + BOOST_THROW_EXCEPTION(OutOfGas()); break; case Instruction::CREATE: @@ -226,6 +228,8 @@ inline bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _st u256 inSize = m_stack[m_stack.size() - 3]; newTempSize = (bigint)inOff + inSize; runGas = c_createGas; + if (_ext.depth == 1024) + BOOST_THROW_EXCEPTION(OutOfGas()); break; } case Instruction::EXP: @@ -566,6 +570,7 @@ inline bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _st break; default: // this is unreachable, but if someone introduces a bug in the future, he may get here. + assert(false); BOOST_THROW_EXCEPTION(InvalidOpcode() << errinfo_comment("CALLDATACOPY, CODECOPY or EXTCODECOPY instruction requested.")); break; } @@ -795,8 +800,6 @@ inline bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _st if (_ext.balance(_ext.myAddress) >= endowment) { - if (_ext.depth == 1024) - BOOST_THROW_EXCEPTION(OutOfGas()); _ext.subBalance(endowment); m_stack.push_back((u160)_ext.create(endowment, m_gas, bytesConstRef(m_temp.data() + initOff, initSize), _onOp)); } @@ -825,8 +828,6 @@ inline bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _st if (_ext.balance(_ext.myAddress) >= value) { - if (_ext.depth == 1024) - BOOST_THROW_EXCEPTION(OutOfGas()); _ext.subBalance(value); m_stack.push_back(_ext.call(inst == Instruction::CALL ? receiveAddress : _ext.myAddress, value, bytesConstRef(m_temp.data() + inOff, inSize), gas, bytesRef(m_temp.data() + outOff, outSize), _onOp, {}, receiveAddress)); } From 71b267d01aaa32786dfbb3dccf520d86f2f77708 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 18 Dec 2014 16:25:44 +0100 Subject: [PATCH 262/277] Update serpent. --- libserpent/bignum.h | 3 + libserpent/compiler.cpp | 279 +++------ libserpent/opcodes.h | 123 +--- libserpent/parser.cpp | 86 +-- libserpent/rewriter.cpp | 1206 +++++++++++++++------------------------ libserpent/tokenize.cpp | 4 +- libserpent/util.cpp | 57 +- libserpent/util.h | 36 +- sc/cmdline.cpp | 13 + 9 files changed, 709 insertions(+), 1098 deletions(-) diff --git a/libserpent/bignum.h b/libserpent/bignum.h index 599365b6c..99571acd2 100644 --- a/libserpent/bignum.h +++ b/libserpent/bignum.h @@ -35,4 +35,7 @@ bool decimalGt(std::string a, std::string b, bool eqAllowed=false); unsigned decimalToUnsigned(std::string a); +#define utd unsignedToDecimal +#define dtu decimalToUnsigned + #endif diff --git a/libserpent/compiler.cpp b/libserpent/compiler.cpp index 30628fbc9..a3e5b1c60 100644 --- a/libserpent/compiler.cpp +++ b/libserpent/compiler.cpp @@ -6,6 +6,7 @@ #include "bignum.h" #include "opcodes.h" +// Auxiliary data that is gathered while compiling struct programAux { std::map vars; int nextVarMem; @@ -13,15 +14,19 @@ struct programAux { bool calldataUsed; int step; int labelLength; - int functionCount; }; +// Auxiliary data that gets passed down vertically +// but not back up struct programVerticalAux { int height; + std::string innerScopeName; std::map dupvars; std::map funvars; + std::vector scopes; }; +// Compilation result struct programData { programAux aux; Node code; @@ -34,7 +39,6 @@ programAux Aux() { o.calldataUsed = false; o.step = 0; o.nextVarMem = 32; - o.functionCount = 0; return o; } @@ -43,6 +47,7 @@ programVerticalAux verticalAux() { o.height = 0; o.dupvars = std::map(); o.funvars = std::map(); + o.scopes = std::vector(); return o; } @@ -72,29 +77,58 @@ Node popwrap(Node node) { return multiToken(nodelist, 2, node.metadata); } +// Grabs variables +mss getVariables(Node node, mss cur=mss()) { + Metadata m = node.metadata; + // Tokens don't contain any variables + if (node.type == TOKEN) + return cur; + // Don't descend into call fragments + else if (node.val == "lll") + return getVariables(node.args[1], cur); + // At global scope get/set/ref also declare + else if (node.val == "get" || node.val == "set" || node.val == "ref") { + if (node.args[0].type != TOKEN) + err("Variable name must be simple token," + " not complex expression! " + printSimple(node.args[0]), m); + if (!cur.count(node.args[0].val)) { + cur[node.args[0].val] = utd(cur.size() * 32 + 32); + //std::cerr << node.args[0].val << " " << cur[node.args[0].val] << "\n"; + } + } + // Recursively process children + for (unsigned i = 0; i < node.args.size(); i++) { + cur = getVariables(node.args[i], cur); + } + return cur; +} + // Turns LLL tree into tree of code fragments programData opcodeify(Node node, programAux aux=Aux(), programVerticalAux vaux=verticalAux()) { std::string symb = "_"+mkUniqueToken(); Metadata m = node.metadata; + // Get variables + if (!aux.vars.size()) { + aux.vars = getVariables(node); + aux.nextVarMem = aux.vars.size() * 32 + 32; + } // Numbers if (node.type == TOKEN) { return pd(aux, nodeToNumeric(node), 1); } - else if (node.val == "ref" || node.val == "get" || - node.val == "set" || node.val == "declare") { + else if (node.val == "ref" || node.val == "get" || node.val == "set") { std::string varname = node.args[0].val; - if (!aux.vars.count(varname)) { - aux.vars[varname] = unsignedToDecimal(aux.nextVarMem); - aux.nextVarMem += 32; - } - if (varname == "'msg.data") aux.calldataUsed = true; + // Determine reference to variable + Node varNode = tkn(aux.vars[varname], m); + //std::cerr << varname << " " << printSimple(varNode) << "\n"; // Set variable if (node.val == "set") { programData sub = opcodeify(node.args[1], aux, vaux); if (!sub.outs) err("Value to set variable must have nonzero arity!", m); + // What if we are setting a stack variable? if (vaux.dupvars.count(node.args[0].val)) { int h = vaux.height - vaux.dupvars[node.args[0].val]; if (h > 16) err("Too deep for stack variable (max 16)", m); @@ -105,149 +139,65 @@ programData opcodeify(Node node, }; return pd(sub.aux, multiToken(nodelist, 3, m), 0); } - Node nodelist[] = { - sub.code, - token(sub.aux.vars[varname], m), - token("MSTORE", m), - }; - return pd(sub.aux, multiToken(nodelist, 3, m), 0); + // Setting a memory variable + else { + Node nodelist[] = { + sub.code, + varNode, + token("MSTORE", m), + }; + return pd(sub.aux, multiToken(nodelist, 3, m), 0); + } } // Get variable else if (node.val == "get") { - if (vaux.dupvars.count(node.args[0].val)) { + // Getting a stack variable + if (vaux.dupvars.count(node.args[0].val)) { int h = vaux.height - vaux.dupvars[node.args[0].val]; if (h > 16) err("Too deep for stack variable (max 16)", m); return pd(aux, token("DUP"+unsignedToDecimal(h)), 1); } - Node nodelist[] = - { token(aux.vars[varname], m), token("MLOAD", m) }; - return pd(aux, multiToken(nodelist, 2, m), 1); + // Getting a memory variable + else { + Node nodelist[] = + { varNode, token("MLOAD", m) }; + return pd(aux, multiToken(nodelist, 2, m), 1); + } } // Refer variable else if (node.val == "ref") { if (vaux.dupvars.count(node.args[0].val)) err("Cannot ref stack variable!", m); - return pd(aux, token(aux.vars[varname], m), 1); - } - // Declare variable - else { - return pd(aux, multiToken(nullptr, 0, m), 0); + return pd(aux, varNode, 1); } } - // Define functions (TODO: eventually move to rewriter.cpp, keep - // compiler pure LLL) - if (node.val == "def") { - std::vector varNames; - std::vector varSizes; - bool useLt32 = false; - int totalSz = 0; - if (node.args.size() != 2) - err("Malformed def!", m); - // Collect the list of variable names and variable byte counts - for (unsigned i = 0; i < node.args[0].args.size(); i++) { - if (node.args[0].args[i].val == "kv") { - if (node.args[0].args[i].args.size() != 2) - err("Malformed def!", m); - varNames.push_back(node.args[0].args[i].args[0].val); - varSizes.push_back( - decimalToUnsigned(node.args[0].args[i].args[1].val)); - if (varSizes.back() > 32) - err("Max argument width: 32 bytes", m); - useLt32 = true; + // Comments do nothing + else if (node.val == "comment") { + Node nodelist[] = { }; + return pd(aux, multiToken(nodelist, 0, m), 0); + } + // Custom operation sequence + // eg. (ops bytez id msize swap1 msize add 0 swap1 mstore) == alloc + if (node.val == "ops") { + std::vector subs2; + int depth = 0; + for (unsigned i = 0; i < node.args.size(); i++) { + std::string op = upperCase(node.args[i].val); + if (node.args[i].type == ASTNODE || opinputs(op) == -1) { + programVerticalAux vaux2 = vaux; + vaux2.height = vaux.height - i - 1 + node.args.size(); + programData sub = opcodeify(node.args[i], aux, vaux2); + aux = sub.aux; + depth += sub.outs; + subs2.push_back(sub.code); } else { - varNames.push_back(node.args[0].args[i].val); - varSizes.push_back(32); + subs2.push_back(token(op, m)); + depth += opoutputs(op) - opinputs(op); } - aux.vars[varNames.back()] = unsignedToDecimal(aux.nextVarMem + 32 * i); - totalSz += varSizes.back(); } - int functionCount = aux.functionCount; - int nextVarMem = aux.nextVarMem; - aux.nextVarMem += 32 * varNames.size(); - aux.functionCount += 1; - programData inner; - // If we're only using 32-byte variables, then great, just copy - // over the calldata! - if (!useLt32) { - programData sub = opcodeify(node.args[1], aux, vaux); - Node nodelist[] = { - token(unsignedToDecimal(totalSz), m), - token("1", m), - token(unsignedToDecimal(nextVarMem), m), - token("CALLDATACOPY", m), - sub.code - }; - inner = pd(sub.aux, multiToken(nodelist, 5, m), 0); - } - else { - std::vector innerList; - int cum = 1; - for (unsigned i = 0; i < varNames.size();) { - // If we get a series of 32-byte values, we calldatacopy them - if (varSizes[i] == 32) { - unsigned until = i+1; - while (until < varNames.size() && varSizes[until] == 32) - until += 1; - innerList.push_back(token(unsignedToDecimal((until - i) * 32), m)); - innerList.push_back(token(unsignedToDecimal(cum), m)); - innerList.push_back(token(unsignedToDecimal(nextVarMem + i * 32), m)); - innerList.push_back(token("CALLDATACOPY", m)); - cum += (until - i) * 32; - i = until; - } - // Otherwise, we do a clever trick to extract the value - else { - innerList.push_back(token(unsignedToDecimal(32 - varSizes[i]), m)); - innerList.push_back(token("256", m)); - innerList.push_back(token("EXP", m)); - innerList.push_back(token(unsignedToDecimal(cum), m)); - innerList.push_back(token("CALLDATALOAD", m)); - innerList.push_back(token("DIV", m)); - innerList.push_back(token(unsignedToDecimal(nextVarMem + i * 32), m)); - innerList.push_back(token("MSTORE", m)); - cum += varSizes[i]; - i += 1; - } - } - // If caller == origin, then it's from a tx, so unpack, otherwise - // plain copy - programData sub = opcodeify(node.args[1], aux, vaux); - Node ilnode = astnode("", innerList, m); - Node nodelist[] = { - token(unsignedToDecimal(32 * varNames.size()), m), - token("1", m), - token(unsignedToDecimal(nextVarMem), m), - token("CALLDATACOPY", m), - token("CALLER", m), - token("ORIGIN", m), - token("EQ", m), - token("ISZERO", m), - token("$maincode"+symb, m), - token("JUMPI", m), - ilnode, - token("~maincode"+symb, m), - token("JUMPDEST", m), - sub.code - }; - inner = pd(sub.aux, multiToken(nodelist, 14, m), 0); - } - // Check if the function call byte is the same - Node nodelist2[] = { - token("0", m), - token("CALLDATALOAD", m), - token("0", m), - token("BYTE", m), - token(unsignedToDecimal(functionCount), m), - token("EQ", m), - token("ISZERO", m), - token("$endcode"+symb, m), - token("JUMPI", m), - inner.code, - token("~endcode"+symb, m), - token("JUMPDEST", m), - }; - return pd(inner.aux, multiToken(nodelist2, 12, m), 0); + if (depth < 0 || depth > 1) err("Stack depth mismatch", m); + return pd(aux, astnode("_", subs2, m), 0); } // Code blocks if (node.val == "lll" && node.args.size() == 2) { @@ -372,49 +322,14 @@ programData opcodeify(Node node, }; return pd(aux, multiToken(nodelist, 8, m), 1); } - // Array literals - else if (node.val == "array_lit") { - aux.allocUsed = true; - std::vector nodes; - if (!node.args.size()) { - nodes.push_back(token("MSIZE", m)); - return pd(aux, astnode("_", nodes, m)); - } - nodes.push_back(token("MSIZE", m)); - nodes.push_back(token("0", m)); - nodes.push_back(token("MSIZE", m)); - nodes.push_back(token(unsignedToDecimal(node.args.size() * 32 - 1), m)); - nodes.push_back(token("ADD", m)); - nodes.push_back(token("MSTORE8", m)); - for (unsigned i = 0; i < node.args.size(); i++) { - Metadata m2 = node.args[i].metadata; - nodes.push_back(token("DUP1", m2)); - programVerticalAux vaux2 = vaux; - vaux2.height += 2; - programData sub = opcodeify(node.args[i], aux, vaux2); - if (!sub.outs) - err("Array_lit item " + unsignedToDecimal(i) + " has zero arity", m2); - aux = sub.aux; - nodes.push_back(sub.code); - nodes.push_back(token("SWAP1", m2)); - if (i > 0) { - nodes.push_back(token(unsignedToDecimal(i * 32), m2)); - nodes.push_back(token("ADD", m2)); - } - nodes.push_back(token("MSTORE", m2)); - } - return pd(aux, astnode("_", nodes, m), 1); - } // All other functions/operators else { std::vector subs2; int depth = opinputs(upperCase(node.val)); - if (node.val != "debug") { - if (depth == -1) - err("Not a function or opcode: "+node.val, m); - if ((int)node.args.size() != depth) - err("Invalid arity for "+node.val, m); - } + if (depth == -1) + err("Not a function or opcode: "+node.val, m); + if ((int)node.args.size() != depth) + err("Invalid arity for "+node.val, m); for (int i = node.args.size() - 1; i >= 0; i--) { programVerticalAux vaux2 = vaux; vaux2.height = vaux.height - i - 1 + node.args.size(); @@ -424,13 +339,8 @@ programData opcodeify(Node node, err("Input "+unsignedToDecimal(i)+" has arity 0", sub.code.metadata); subs2.push_back(sub.code); } - if (node.val == "debug") { - subs2.push_back(token("DUP"+unsignedToDecimal(node.args.size()), m)); - for (int i = 0; i <= (int)node.args.size(); i++) - subs2.push_back(token("POP", m)); - } - else subs2.push_back(token(upperCase(node.val), m)); - int outdepth = node.val == "debug" ? 0 : opoutputs(upperCase(node.val)); + subs2.push_back(token(upperCase(node.val), m)); + int outdepth = opoutputs(upperCase(node.val)); return pd(aux, astnode("_", subs2, m), outdepth); } } @@ -449,15 +359,6 @@ Node finalize(programData c) { }; bottom.push_back(multiToken(nodelist, 3, m)); } - // If msg.data is being used as an array, then we need to copy it - if (c.aux.calldataUsed) { - Node nodelist[] = { - token("MSIZE", m), token("CALLDATASIZE", m), token("0", m), - token("MSIZE", m), token("CALLDATACOPY", m), - token(c.aux.vars["'msg.data"], m), token("MSTORE", m) - }; - bottom.push_back(multiToken(nodelist, 7, m)); - } // The actual code bottom.push_back(c.code); return astnode("_", bottom, m); diff --git a/libserpent/opcodes.h b/libserpent/opcodes.h index a7bcc1af9..41423c169 100644 --- a/libserpent/opcodes.h +++ b/libserpent/opcodes.h @@ -5,6 +5,7 @@ #include #include #include +#include "util.h" class Mapping { public: @@ -20,119 +21,25 @@ class Mapping { int out; }; -Mapping mapping[] = { - Mapping("STOP", 0x00, 0, 0), - Mapping("ADD", 0x01, 2, 1), - Mapping("MUL", 0x02, 2, 1), - Mapping("SUB", 0x03, 2, 1), - Mapping("DIV", 0x04, 2, 1), - Mapping("SDIV", 0x05, 2, 1), - Mapping("MOD", 0x06, 2, 1), - Mapping("SMOD", 0x07, 2, 1), - Mapping("ADDMOD", 0x08, 3, 1), - Mapping("MULMOD", 0x09, 3, 1), - Mapping("EXP", 0x0a, 2, 1), - Mapping("SIGNEXTEND", 0x0b, 2, 1), - Mapping("LT", 0x10, 2, 1), - Mapping("GT", 0x11, 2, 1), - Mapping("SLT", 0x12, 2, 1), - Mapping("SGT", 0x13, 2, 1), - Mapping("EQ", 0x14, 2, 1), - Mapping("ISZERO", 0x15, 1, 1), - Mapping("AND", 0x16, 2, 1), - Mapping("OR", 0x17, 2, 1), - Mapping("XOR", 0x18, 2, 1), - Mapping("NOT", 0x19, 1, 1), - Mapping("BYTE", 0x1a, 2, 1), - Mapping("ADDMOD", 0x14, 3, 1), - Mapping("MULMOD", 0x15, 3, 1), - Mapping("SIGNEXTEND", 0x16, 2, 1), - Mapping("SHA3", 0x20, 2, 1), - Mapping("ADDRESS", 0x30, 0, 1), - Mapping("BALANCE", 0x31, 1, 1), - Mapping("ORIGIN", 0x32, 0, 1), - Mapping("CALLER", 0x33, 0, 1), - Mapping("CALLVALUE", 0x34, 0, 1), - Mapping("CALLDATALOAD", 0x35, 1, 1), - Mapping("CALLDATASIZE", 0x36, 0, 1), - Mapping("CALLDATACOPY", 0x37, 3, 1), - Mapping("CODESIZE", 0x38, 0, 1), - Mapping("CODECOPY", 0x39, 3, 1), - Mapping("GASPRICE", 0x3a, 0, 1), - Mapping("PREVHASH", 0x40, 0, 1), - Mapping("COINBASE", 0x41, 0, 1), - Mapping("TIMESTAMP", 0x42, 0, 1), - Mapping("NUMBER", 0x43, 0, 1), - Mapping("DIFFICULTY", 0x44, 0, 1), - Mapping("GASLIMIT", 0x45, 0, 1), - Mapping("POP", 0x50, 1, 0), - Mapping("MLOAD", 0x51, 1, 1), - Mapping("MSTORE", 0x52, 2, 0), - Mapping("MSTORE8", 0x53, 2, 0), - Mapping("SLOAD", 0x54, 1, 1), - Mapping("SSTORE", 0x55, 2, 0), - Mapping("JUMP", 0x56, 1, 0), - Mapping("JUMPI", 0x57, 2, 0), - Mapping("PC", 0x58, 0, 1), - Mapping("MSIZE", 0x59, 0, 1), - Mapping("GAS", 0x5a, 0, 1), - Mapping("JUMPDEST", 0x5b, 0, 0), - Mapping("LOG0", 0xa0, 2, 0), - Mapping("LOG1", 0xa1, 3, 0), - Mapping("LOG2", 0xa2, 4, 0), - Mapping("LOG3", 0xa3, 5, 0), - Mapping("LOG4", 0xa4, 6, 0), - Mapping("CREATE", 0xf0, 3, 1), - Mapping("CALL", 0xf1, 7, 1), - Mapping("RETURN", 0xf2, 2, 0), - Mapping("CALL_CODE", 0xf3, 7, 1), - Mapping("SUICIDE", 0xff, 1, 0), - Mapping("---END---", 0x00, 0, 0), -}; +extern Mapping mapping[]; -std::map > opcodes; -std::map reverseOpcodes; +extern std::map > opcodes; +extern std::map reverseOpcodes; -// Fetches everything EXCEPT PUSH1..32 -std::pair > _opdata(std::string ops, int opi) { - if (!opcodes.size()) { - int i = 0; - while (mapping[i].op != "---END---") { - Mapping mi = mapping[i]; - opcodes[mi.op] = triple(mi.opcode, mi.in, mi.out); - i++; - } - for (i = 1; i <= 16; i++) { - opcodes["DUP"+unsignedToDecimal(i)] = triple(0x7f + i, i, i+1); - opcodes["SWAP"+unsignedToDecimal(i)] = triple(0x8f + i, i+1, i+1); - } - for (std::map >::iterator it=opcodes.begin(); - it != opcodes.end(); - it++) { - reverseOpcodes[(*it).second[0]] = (*it).first; - } - } - std::string op; - std::vector opdata; - op = reverseOpcodes.count(opi) ? reverseOpcodes[opi] : ""; - opdata = opcodes.count(ops) ? opcodes[ops] : triple(-1, -1, -1); - return std::pair >(op, opdata); -} +std::pair > _opdata(std::string ops, int opi); + +int opcode(std::string op); + +int opinputs(std::string op); + +int opoutputs(std::string op); -int opcode(std::string op) { - return _opdata(op, -1).second[0]; -} +std::string op(int opcode); -int opinputs(std::string op) { - return _opdata(op, -1).second[1]; -} +extern std::string lllSpecials[][3]; -int opoutputs(std::string op) { - return _opdata(op, -1).second[2]; -} +extern std::map > lllMap; -std::string op(int opcode) { - return _opdata("", opcode).first; -} +bool isValidLLLFunc(std::string f, int argc); #endif diff --git a/libserpent/parser.cpp b/libserpent/parser.cpp index 4ceb1d12d..2b9d73702 100644 --- a/libserpent/parser.cpp +++ b/libserpent/parser.cpp @@ -12,17 +12,15 @@ int precedence(Node tok) { if (v == ".") return -1; else if (v == "!" || v == "not") return 1; else if (v=="^" || v == "**") return 2; - else if (v=="*" || v=="/" || v=="@/" || v=="%" || v=="@%") return 3; + else if (v=="*" || v=="/" || v=="%") return 3; else if (v=="+" || v=="-") return 4; else if (v=="<" || v==">" || v=="<=" || v==">=") return 5; - else if (v=="@<" || v=="@>" || v=="@<=" || v=="@>=") return 5; else if (v=="&" || v=="|" || v=="xor" || v=="==" || v == "!=") return 6; else if (v=="&&" || v=="and") return 7; else if (v=="||" || v=="or") return 8; - else if (v==":") return 9; else if (v=="=") return 10; else if (v=="+=" || v=="-=" || v=="*=" || v=="/=" || v=="%=") return 10; - else if (v=="@/=" || v=="@%=") return 10; + else if (v==":" || v == "::") return 11; else return 0; } @@ -223,8 +221,15 @@ Node treefy(std::vector stream) { filename = filename.substr(1, filename.length() - 2); if (!exists(root + filename)) err("File does not exist: "+root + filename, tok.metadata); - oq.back().args.pop_back(); - oq.back().args.push_back(parseSerpent(root + filename)); + if (v == "inset") { + oq.pop_back(); + oq.push_back(parseSerpent(root + filename)); + } + else { + oq.back().args.pop_back(); + oq.back().args.push_back( + asn("outer", parseSerpent(root + filename), tok.metadata)); + } } //Useful for debugging //for (int i = 0; i < oq.size(); i++) { @@ -237,7 +242,7 @@ Node treefy(std::vector stream) { err("Output blank", Metadata()); } else if (oq.size() > 1) { - err("Multiple expressions or unclosed bracket", oq[1].metadata); + return asn("multi", oq, oq[0].metadata); } return oq[0]; @@ -262,15 +267,9 @@ int spaceCount(std::string s) { bool bodied(std::string tok) { return tok == "if" || tok == "elif" || tok == "while" || tok == "with" || tok == "def" || tok == "extern" - || tok == "data"; -} - -// Is this a command that takes an argument as a child block? -bool childBlocked(std::string tok) { - return tok == "if" || tok == "elif" || tok == "else" - || tok == "code" || tok == "shared" || tok == "init" - || tok == "while" || tok == "repeat" || tok == "for" - || tok == "with" || tok == "def"; + || tok == "data" || tok == "assert" || tok == "return" + || tok == "fun" || tok == "scope" || tok == "macro" + || tok == "type"; } // Are the two commands meant to continue each other? @@ -278,10 +277,7 @@ bool bodiedContinued(std::string prev, std::string tok) { return (prev == "if" && tok == "elif") || (prev == "elif" && tok == "else") || (prev == "elif" && tok == "elif") - || (prev == "if" && tok == "else") - || (prev == "init" && tok == "code") - || (prev == "shared" && tok == "code") - || (prev == "shared" && tok == "init"); + || (prev == "if" && tok == "else"); } // Is a line of code empty? @@ -310,16 +306,17 @@ Node parseLines(std::vector lines, Metadata metadata, int sp) { } // Tokenize current line std::vector tokens = tokenize(main.substr(sp), metadata); - // Remove extraneous tokens, including if / elif + // Remove comments std::vector tokens2; for (unsigned j = 0; j < tokens.size(); j++) { if (tokens[j].val == "#" || tokens[j].val == "//") break; - if (j >= 1 || !bodied(tokens[j].val)) { - tokens2.push_back(tokens[j]); - } + tokens2.push_back(tokens[j]); } - if (tokens2.size() > 0 && tokens2.back().val == ":") + bool expectingChildBlock = false; + if (tokens2.size() > 0 && tokens2.back().val == ":") { tokens2.pop_back(); + expectingChildBlock = true; + } // Parse current line Node out = parseSerpentTokenStream(tokens2); // Parse child block @@ -343,14 +340,8 @@ Node parseLines(std::vector lines, Metadata metadata, int sp) { for (unsigned i = 0; i < childBlock.size(); i++) { if (childBlock[i].length() > 0) { cbe = false; break; } } - // Bring back if / elif into AST - if (bodied(tokens[0].val)) { - std::vector args; - args.push_back(out); - out = astnode(tokens[0].val, args, out.metadata); - } // Add child block to AST - if (childBlocked(tokens[0].val)) { + if (expectingChildBlock) { if (cbe) err("Expected indented child block!", out.metadata); out.type = ASTNODE; @@ -360,6 +351,37 @@ Node parseLines(std::vector lines, Metadata metadata, int sp) { } else if (!cbe) err("Did not expect indented child block!", out.metadata); + else if (out.args.size() && out.args[out.args.size() - 1].val == ":") { + Node n = out.args[out.args.size() - 1]; + out.args.pop_back(); + out.args.push_back(n.args[0]); + out.args.push_back(n.args[1]); + } + // Bring back if / elif into AST + if (bodied(tokens[0].val)) { + if (out.val != "multi") { + // token not being used in bodied form + } + else if (out.args[0].val == "id") + out = astnode(tokens[0].val, out.args[1].args, out.metadata); + else if (out.args[0].type == TOKEN) { + std::vector out2; + for (unsigned i = 1; i < out.args.size(); i++) + out2.push_back(out.args[i]); + out = astnode(tokens[0].val, out2, out.metadata); + } + else + out = astnode("fun", out.args, out.metadata); + } + // Multi not supported + if (out.val == "multi") + err("Multiple expressions or unclosed bracket", out.metadata); + // Convert top-level colon expressions into non-colon expressions; + // makes if statements and the like equivalent indented or not + //if (out.val == ":" && out.args[0].type == TOKEN) + // out = asn(out.args[0].val, out.args[1], out.metadata); + //if (bodied(tokens[0].val) && out.args[0].val == ":") + // out = asn(tokens[0].val, out.args[0].args); if (o.size() == 0 || o.back().type == TOKEN) { o.push_back(out); continue; diff --git a/libserpent/rewriter.cpp b/libserpent/rewriter.cpp index 443457acf..294c9a0b3 100644 --- a/libserpent/rewriter.cpp +++ b/libserpent/rewriter.cpp @@ -2,37 +2,25 @@ #include #include #include -#include #include "util.h" #include "lllparser.h" #include "bignum.h" +#include "optimize.h" +#include "rewriteutils.h" +#include "preprocess.h" +#include "functions.h" +#include "opcodes.h" -std::string valid[][3] = { - { "if", "2", "3" }, - { "unless", "2", "2" }, - { "while", "2", "2" }, - { "until", "2", "2" }, - { "alloc", "1", "1" }, - { "array", "1", "1" }, - { "call", "2", tt256 }, - { "call_code", "2", tt256 }, - { "create", "1", "4" }, - { "getch", "2", "2" }, - { "setch", "3", "3" }, - { "sha3", "1", "2" }, - { "return", "1", "2" }, - { "inset", "1", "1" }, - { "min", "2", "2" }, - { "max", "2", "2" }, - { "array_lit", "0", tt256 }, - { "seq", "0", tt256 }, - { "log", "1", "6" }, - { "outer", "1", "1" }, - { "set", "2", "2" }, - { "---END---", "", "" } //Keep this line at the end of the list -}; - +// Rewrite rules std::string macros[][2] = { + { + "(seq $x)", + "$x" + }, + { + "(seq (seq) $x)", + "$x" + }, { "(+= $a $b)", "(set $a (+ $a $b))" @@ -58,24 +46,28 @@ std::string macros[][2] = { "(set $a (^ $a $b))" }, { - "(@/= $a $b)", - "(set $a (@/ $a $b))" + "(!= $a $b)", + "(iszero (eq $a $b))" }, { - "(@%= $a $b)", - "(set $a (@% $a $b))" + "(assert $x)", + "(unless $x (stop))" }, { - "(!= $a $b)", - "(iszero (eq $a $b))" + "(min $a $b)", + "(with $1 $a (with $2 $b (if (lt $1 $2) $1 $2)))" + }, + { + "(max $a $b)", + "(with $1 $a (with $2 $b (if (lt $1 $2) $2 $1)))" }, { - "(min a b)", - "(with $1 a (with $2 b (if (lt $1 $2) $1 $2)))" + "(smin $a $b)", + "(with $1 $a (with $2 $b (if (slt $1 $2) $1 $2)))" }, { - "(max a b)", - "(with $1 a (with $2 b (if (lt $1 $2) $2 $1)))" + "(smax $a $b)", + "(with $1 $a (with $2 $b (if (slt $1 $2) $2 $1)))" }, { "(if $cond $do (else $else))", @@ -85,10 +77,6 @@ std::string macros[][2] = { "(code $code)", "$code" }, - { - "(access (. msg data) $ind)", - "(calldataload (mul 32 $ind))" - }, { "(slice $arr $pos)", "(add $arr (mul 32 $pos))", @@ -125,13 +113,17 @@ std::string macros[][2] = { "(set (access (. self storage) $ind) $val)", "(sstore $ind $val)" }, + { + "(set (sload $ind) $val)", + "(sstore $ind $val)" + }, { "(set (access $var $ind) $val)", "(mstore (add $var (mul 32 $ind)) $val)" }, { "(getch $var $ind)", - "(mod (mload (add $var $ind)) 256)" + "(mod (mload (sub (add $var $ind) 31)) 256)" }, { "(setch $var $ind $val)", @@ -149,6 +141,10 @@ std::string macros[][2] = { "(sha3 $x)", "(seq (set $1 $x) (~sha3 (ref $1) 32))" }, + { + "(sha3 $mstart (= chars $msize))", + "(~sha3 $mstart $msize)" + }, { "(sha3 $mstart $msize)", "(~sha3 $mstart (mul 32 $msize))" @@ -161,6 +157,10 @@ std::string macros[][2] = { "(return $x)", "(seq (set $1 $x) (~return (ref $1) 32))" }, + { + "(return $mstart (= chars $msize))", + "(~return $mstart $msize)" + }, { "(return $start $len)", "(~return $start (mul 32 $len))" @@ -171,7 +171,7 @@ std::string macros[][2] = { }, { "(|| $x $y)", - "(with $1 $x (if (get $1) (get $1) $y))" + "(with $1 $x (if $1 $1 $y))" }, { "(>= $x $y)", @@ -181,45 +181,41 @@ std::string macros[][2] = { "(<= $x $y)", "(iszero (sgt $x $y))" }, - { - "(@>= $x $y)", - "(iszero (lt $x $y))" - }, - { - "(@<= $x $y)", - "(iszero (gt $x $y))" - }, { "(create $code)", "(create 0 $code)" }, { "(create $endowment $code)", - "(with $1 (msize) (create $endowment (get $1) (lll (outer $code) (msize))))" + "(with $1 (msize) (create $endowment (get $1) (lll $code (msize))))" }, { "(sha256 $x)", - "(seq (set $1 $x) (pop (~call 101 2 0 (ref $1) 32 (ref $2) 32)) (get $2))" + "(with $1 (alloc 64) (seq (mstore (add (get $1) 32) $x) (pop (~call 101 2 0 (add (get $1) 32) 32 (get $1) 32)) (mload (get $1))))" + }, + { + "(sha256 $arr (= chars $sz))", + "(with $1 (alloc 32) (seq (pop (~call 101 2 0 $arr $sz (get $1) 32)) (mload (get $1))))" }, { "(sha256 $arr $sz)", - "(seq (pop (~call 101 2 0 $arr (mul 32 $sz) (ref $2) 32)) (get $2))" + "(with $1 (alloc 32) (seq (pop (~call 101 2 0 $arr (mul 32 $sz) (get $1) 32)) (mload (get $1))))" }, { "(ripemd160 $x)", - "(seq (set $1 $x) (pop (~call 101 3 0 (ref $1) 32 (ref $2) 32)) (get $2))" + "(with $1 (alloc 64) (seq (mstore (add (get $1) 32) $x) (pop (~call 101 3 0 (add (get $1) 32) 32 (get $1) 32)) (mload (get $1))))" }, { - "(ripemd160 $arr $sz)", - "(seq (pop (~call 101 3 0 $arr (mul 32 $sz) (ref $2) 32)) (get $2))" + "(ripemd160 $arr (= chars $sz))", + "(with $1 (alloc 32) (seq (pop (~call 101 3 0 $arr $sz (mload $1) 32)) (mload (get $1))))" }, { - "(ecrecover $h $v $r $s)", - "(seq (declare $1) (declare $2) (declare $3) (declare $4) (set $1 $h) (set $2 $v) (set $3 $r) (set $4 $s) (pop (~call 101 1 0 (ref $1) 128 (ref $5) 32)) (get $5))" + "(ripemd160 $arr $sz)", + "(with $1 (alloc 32) (seq (pop (~call 101 3 0 $arr (mul 32 $sz) (get $1) 32)) (mload (get $1))))" }, { - "(seq (seq) $x)", - "$x" + "(ecrecover $h $v $r $s)", + "(with $1 (alloc 160) (seq (mstore (get $1) $h) (mstore (add (get $1) 32) $v) (mstore (add (get $1) 64) $r) (mstore (add (get $1) 96) $s) (pop (~call 101 1 0 (get $1) 128 (add (get $1 128)) 32)) (mload (add (get $1) 128))))" }, { "(inset $x)", @@ -235,21 +231,64 @@ std::string macros[][2] = { }, { "(log $t1)", - "(~log1 $t1 0 0)" + "(~log1 0 0 $t1)" }, { "(log $t1 $t2)", - "(~log2 $t1 $t2 0 0)" + "(~log2 0 0 $t1 $t2)" }, { "(log $t1 $t2 $t3)", - "(~log3 $t1 $t2 $t3 0 0)" + "(~log3 0 0 $t1 $t2 $t3)" }, { "(log $t1 $t2 $t3 $t4)", - "(~log4 $t1 $t2 $t3 $t4 0 0)" + "(~log4 0 0 $t1 $t2 $t3 $t4)" + }, + { + "(logarr $a $sz)", + "(~log0 $a (mul 32 $sz))" + }, + { + "(logarr $a $sz $t1)", + "(~log1 $a (mul 32 $sz) $t1)" + }, + { + "(logarr $a $sz $t1 $t2)", + "(~log2 $a (mul 32 $sz) $t1 $t2)" + }, + { + "(logarr $a $sz $t1 $t2 $t3)", + "(~log3 $a (mul 32 $sz) $t1 $t2 $t3)" + }, + { + "(logarr $a $sz $t1 $t2 $t3 $t4)", + "(~log4 $a (mul 32 $sz) $t1 $t2 $t3 $t4)" + }, + { + "(save $loc $array (= chars $count))", + "(with $location (ref $loc) (with $c $count (with $end (div $c 32) (with $i 0 (seq (while (slt $i $end) (seq (sstore (add $i $location) (access $array $i)) (set $i (add $i 1)))) (sstore (add $i $location) (~and (access $array $i) (sub 0 (exp 256 (sub 32 (mod $c 32)))))))))))" + }, + { + "(save $loc $array $count)", + "(with $location (ref $loc) (with $end $count (with $i 0 (while (slt $i $end) (seq (sstore (add $i $location) (access $array $i)) (set $i (add $i 1)))))))" + }, + { + "(load $loc (= chars $count))", + "(with $location (ref $loc) (with $c $count (with $a (alloc $c) (with $i 0 (seq (while (slt $i (div $c 32)) (seq (set (access $a $i) (sload (add $location $i))) (set $i (add $i 1)))) (set (access $a $i) (~and (sload (add $location $i)) (sub 0 (exp 256 (sub 32 (mod $c 32)))))) $a)))))" + }, + { + "(load $loc $count)", + "(with $location (ref $loc) (with $c $count (with $a (alloc $c) (with $i 0 (seq (while (slt $i $c) (seq (set (access $a $i) (sload (add $location $i))) (set $i (add $i 1)))) $a)))))" + }, + { + "(unsafe_mcopy $to $from $sz)", + "(with _sz $sz (with _from $from (with _to $to (seq (comment STARTING UNSAFE MCOPY) (with _i 0 (while (lt _i _sz) (seq (mstore (add $to _i) (mload (add _from _i))) (set _i (add _i 32)))))))))" + }, + { + "(mcopy $to $from $_sz)", + "(with _to $to (with _from $from (with _sz $sz (seq (comment STARTING MCOPY (with _i 0 (seq (while (lt (add _i 31) _sz) (seq (mstore (add _to _i) (mload (add _from _i))) (set _i (add _i 32)))) (with _mask (exp 256 (sub 32 (mod _sz 32))) (mstore (add $to _i) (add (mod (mload (add $to _i)) _mask) (and (mload (add $from _i)) (sub 0 _mask))))))))))))" }, - { "(. msg datasize)", "(div (calldatasize) 32)" }, { "(. msg sender)", "(caller)" }, { "(. msg value)", "(callvalue)" }, { "(. tx gasprice)", "(gasprice)" }, @@ -267,8 +306,7 @@ std::string macros[][2] = { { "---END---", "" } //Keep this line at the end of the list }; -std::vector > nodeMacros; - +// Token synonyms std::string synonyms[][2] = { { "or", "||" }, { "and", "&&" }, @@ -286,10 +324,6 @@ std::string synonyms[][2] = { { "^", "exp" }, { "**", "exp" }, { "%", "smod" }, - { "@/", "div" }, - { "@%", "mod" }, - { "@<", "lt" }, - { "@>", "gt" }, { "<", "slt" }, { ">", "sgt" }, { "=", "set" }, @@ -298,6 +332,10 @@ std::string synonyms[][2] = { { "---END---", "" } //Keep this line at the end of the list }; +std::map synonymMap; + +// Custom setters (need to be registered separately +// for use with managed storage) std::string setters[][2] = { { "+=", "+" }, { "-=", "-" }, @@ -305,550 +343,136 @@ std::string setters[][2] = { { "/=", "/" }, { "%=", "%" }, { "^=", "^" }, - { "!=", "!" }, { "---END---", "" } //Keep this line at the end of the list }; -// Match result storing object -struct matchResult { - bool success; - std::map map; -}; - -// Storage variable index storing object -struct svObj { - std::map offsets; - std::map indices; - std::map > coefficients; - std::map nonfinal; - std::string globalOffset; -}; - -// Preprocessing result storing object -class preprocessAux { - public: - preprocessAux() { - globalExterns = std::map(); - localExterns = std::map >(); - localExterns["self"] = std::map(); - } - std::map globalExterns; - std::map > localExterns; - svObj storageVars; -}; - -#define preprocessResult std::pair - -// Main pattern matching routine, for those patterns that can be expressed -// using our standard mini-language above -// -// Returns two values. First, a boolean to determine whether the node matches -// the pattern, second, if the node does match then a map mapping variables -// in the pattern to nodes -matchResult match(Node p, Node n) { - matchResult o; - o.success = false; - if (p.type == TOKEN) { - if (p.val == n.val && n.type == TOKEN) o.success = true; - else if (p.val[0] == '$') { - o.success = true; - o.map[p.val.substr(1)] = n; - } - } - else if (n.type==TOKEN || p.val!=n.val || p.args.size()!=n.args.size()) { - // do nothing - } - else { - for (unsigned i = 0; i < p.args.size(); i++) { - matchResult oPrime = match(p.args[i], n.args[i]); - if (!oPrime.success) { - o.success = false; - return o; - } - for (std::map::iterator it = oPrime.map.begin(); - it != oPrime.map.end(); - it++) { - o.map[(*it).first] = (*it).second; - } - } - o.success = true; - } - return o; -} - -// Fills in the pattern with a dictionary mapping variable names to -// nodes (these dicts are generated by match). Match and subst together -// create a full pattern-matching engine. -Node subst(Node pattern, - std::map dict, - std::string varflag, - Metadata metadata) { - if (pattern.type == TOKEN && pattern.val[0] == '$') { - if (dict.count(pattern.val.substr(1))) { - return dict[pattern.val.substr(1)]; - } - else { - return token(varflag + pattern.val.substr(1), metadata); - } - } - else if (pattern.type == TOKEN) { - return pattern; - } - else { - std::vector args; - for (unsigned i = 0; i < pattern.args.size(); i++) { - args.push_back(subst(pattern.args[i], dict, varflag, metadata)); - } - return astnode(pattern.val, args, metadata); - } -} +std::map setterMap; // Processes mutable array literals - Node array_lit_transform(Node node) { + std::string prefix = "_temp"+mkUniqueToken() + "_"; Metadata m = node.metadata; - std::vector o1; - o1.push_back(token(unsignedToDecimal(node.args.size() * 32), m)); - std::vector o2; - std::string symb = "_temp"+mkUniqueToken()+"_0"; - o2.push_back(token(symb, m)); - o2.push_back(astnode("alloc", o1, m)); - std::vector o3; - o3.push_back(astnode("set", o2, m)); + std::map d; + std::string o = "(seq (set $arr (alloc "+utd(node.args.size()*32)+"))"; for (unsigned i = 0; i < node.args.size(); i++) { - std::vector o5; - o5.push_back(token(symb, m)); - std::vector o6; - o6.push_back(astnode("get", o5, m)); - o6.push_back(token(unsignedToDecimal(i * 32), m)); - std::vector o7; - o7.push_back(astnode("add", o6)); - o7.push_back(node.args[i]); - o3.push_back(astnode("mstore", o7, m)); - } - std::vector o8; - o8.push_back(token(symb, m)); - o3.push_back(astnode("get", o8)); - return astnode("seq", o3, m); -} - -// Is the given node something of the form -// self.cow -// self.horse[0] -// self.a[6][7][self.storage[3]].chicken[9] -bool isNodeStorageVariable(Node node) { - std::vector nodez; - nodez.push_back(node); - while (1) { - if (nodez.back().type == TOKEN) return false; - if (nodez.back().args.size() == 0) return false; - if (nodez.back().val != "." && nodez.back().val != "access") - return false; - if (nodez.back().args[0].val == "self") return true; - nodez.push_back(nodez.back().args[0]); + o += " (mstore (add (get $arr) "+utd(i * 32)+") $"+utd(i)+")"; + d[utd(i)] = node.args[i]; } + o += " (get $arr))"; + return subst(parseLLL(o), d, prefix, m); } -Node optimize(Node inp); - -Node apply_rules(preprocessResult pr); - -// Convert: -// self.cow -> ["cow"] -// self.horse[0] -> ["horse", "0"] -// self.a[6][7][self.storage[3]].chicken[9] -> -// ["6", "7", (sload 3), "chicken", "9"] -std::vector listfyStorageAccess(Node node) { - std::vector out; - std::vector nodez; - nodez.push_back(node); - while (1) { - if (nodez.back().type == TOKEN) { - out.push_back(token("--" + nodez.back().val, node.metadata)); - std::vector outrev; - for (int i = (signed)out.size() - 1; i >= 0; i--) { - outrev.push_back(out[i]); +// Processes long text literals +Node string_transform(Node node) { + Metadata m = node.metadata; + if (!node.args.size()) + err("Empty text!", m); + if (node.args[0].val.size() < 2 + || node.args[0].val[0] != '"' + || node.args[0].val[node.args[0].val.size() - 1] != '"') + err("Text contents don't look like a string!", m); + std::string bin = node.args[0].val.substr(1, node.args[0].val.size() - 2); + unsigned sz = bin.size(); + std::vector o; + for (unsigned i = 0; i < sz; i += 32) { + std::string t = binToNumeric(bin.substr(i, 32)); + if ((sz - i) < 32 && (sz - i) > 0) { + while ((sz - i) < 32) { + t = decimalMul(t, "256"); + i--; } - return outrev; + i = sz; } - if (nodez.back().val == ".") - nodez.back().args[1].val = "--" + nodez.back().args[1].val; - if (nodez.back().args.size() == 0) - err("Error parsing storage variable statement", node.metadata); - if (nodez.back().args.size() == 1) - out.push_back(token(tt256m1, node.metadata)); - else - out.push_back(nodez.back().args[1]); - nodez.push_back(nodez.back().args[0]); + o.push_back(token(t, node.metadata)); } + node = astnode("array_lit", o, node.metadata); + return array_lit_transform(node); } -// Cool function for debug purposes (named cerrStringList to make -// all prints searchable via 'cerr') -void cerrStringList(std::vector s, std::string suffix="") { - for (unsigned i = 0; i < s.size(); i++) std::cerr << s[i] << " "; - std::cerr << suffix << "\n"; -} -// Populate an svObj with the arguments needed to determine -// the storage position of a node -svObj getStorageVars(svObj pre, Node node, std::string prefix="", int index=0) { - Metadata m = node.metadata; - if (!pre.globalOffset.size()) pre.globalOffset = "0"; - std::vector h; - std::vector coefficients; - // Array accesses or atoms - if (node.val == "access" || node.type == TOKEN) { - std::string tot = "1"; - h = listfyStorageAccess(node); - coefficients.push_back("1"); - for (unsigned i = h.size() - 1; i >= 1; i--) { - // Array sizes must be constant or at least arithmetically - // evaluable at compile time - h[i] = optimize(apply_rules(preprocessResult( - h[i], preprocessAux()))); - if (!isNumberLike(h[i])) - err("Array size must be fixed value", m); - // Create a list of the coefficient associated with each - // array index - coefficients.push_back(decimalMul(coefficients.back(), h[i].val)); - } - } - // Tuples - else { - int startc; - // Handle the (fun args...) case - if (node.val == "fun") { - startc = 1; - h = listfyStorageAccess(node.args[0]); - } - // Handle the ( args...) case, which - // the serpent parser produces when the function - // is a simple name and not a complex astnode - else { - startc = 0; - h = listfyStorageAccess(token(node.val, m)); - } - svObj sub = pre; - sub.globalOffset = "0"; - // Evaluate tuple elements recursively - for (unsigned i = startc; i < node.args.size(); i++) { - sub = getStorageVars(sub, - node.args[i], - prefix+h[0].val.substr(2)+".", - i-1); - } - coefficients.push_back(sub.globalOffset); - for (unsigned i = h.size() - 1; i >= 1; i--) { - // Array sizes must be constant or at least arithmetically - // evaluable at compile time - h[i] = optimize(apply_rules(preprocessResult( - h[i], preprocessAux()))); - if (!isNumberLike(h[i])) - err("Array size must be fixed value", m); - // Create a list of the coefficient associated with each - // array index - coefficients.push_back(decimalMul(coefficients.back(), h[i].val)); - } - pre.offsets = sub.offsets; - pre.coefficients = sub.coefficients; - pre.nonfinal = sub.nonfinal; - pre.nonfinal[prefix+h[0].val.substr(2)] = true; - } - pre.coefficients[prefix+h[0].val.substr(2)] = coefficients; - pre.offsets[prefix+h[0].val.substr(2)] = pre.globalOffset; - pre.indices[prefix+h[0].val.substr(2)] = index; - if (decimalGt(tt176, coefficients.back())) - pre.globalOffset = decimalAdd(pre.globalOffset, coefficients.back()); - return pre; -} +Node apply_rules(preprocessResult pr); -// Transform a node of the form (call to funid vars...) into +// Transform ".(args...)" into // a call - -#define psn std::pair - -Node call_transform(Node node, std::string op) { +Node dotTransform(Node node, preprocessAux aux) { Metadata m = node.metadata; // We're gonna make lots of temporary variables, // so set up a unique flag for them std::string prefix = "_temp"+mkUniqueToken()+"_"; + // Check that the function name is a token + if (node.args[0].args[1].type == ASTNODE) + err("Function name must be static", m); + + Node dotOwner = node.args[0].args[0]; + std::string dotMember = node.args[0].args[1].val; // kwargs = map of special arguments std::map kwargs; kwargs["value"] = token("0", m); - kwargs["gas"] = parseLLL("(- (gas) 25)"); - std::vector args; - for (unsigned i = 0; i < node.args.size(); i++) { - if (node.args[i].val == "=" || node.args[i].val == "set") { - if (node.args[i].args.size() != 2) - err("Malformed set", m); - kwargs[node.args[i].args[0].val] = node.args[i].args[1]; - } - else args.push_back(node.args[i]); - } - if (args.size() < 2) err("Too few arguments for call!", m); - kwargs["to"] = args[0]; - kwargs["funid"] = args[1]; - std::vector inputs; - for (unsigned i = 2; i < args.size(); i++) { - inputs.push_back(args[i]); - } - std::vector with; - std::vector precompute; - std::vector post; - if (kwargs.count("data")) { - if (!kwargs.count("datasz")) err("Required param datasz", m); - // The strategy here is, we store the function ID byte at the index - // before the start of the byte, but then we store the value that was - // there before and reinstate it once the process is over - // store data: data array start - with.push_back(psn(prefix+"data", kwargs["data"])); - // store data: prior: data array - 32 - Node prior = astnode("sub", token(prefix+"data", m), token("32", m), m); - with.push_back(psn(prefix+"prior", prior)); - // store data: priormem: data array - 32 prior memory value - Node priormem = astnode("mload", token(prefix+"prior", m), m); - with.push_back(psn(prefix+"priormem", priormem)); - // post: reinstate prior mem at data array - 32 - post.push_back(astnode("mstore", - token(prefix+"prior", m), - token(prefix+"priormem", m), - m)); - // store data: datastart: data array - 1 - Node datastart = astnode("sub", - token(prefix+"data", m), - token("1", m), - m); - with.push_back(psn(prefix+"datastart", datastart)); - // push funid byte to datastart - precompute.push_back(astnode("mstore8", - token(prefix+"datastart", m), - kwargs["funid"], - m)); - // set data array start loc - kwargs["datain"] = token(prefix+"datastart", m); - kwargs["datainsz"] = astnode("add", - token("1", m), - astnode("mul", - token("32", m), - kwargs["datasz"], - m), - m); - } - else { - // Here, there is no data array, instead there are function arguments. - // This actually lets us be much more efficient with how we set things - // up. - // Pre-declare variables; relies on declared variables being sequential - precompute.push_back(astnode("declare", - token(prefix+"prebyte", m), - m)); - for (unsigned i = 0; i < inputs.size(); i++) { - precompute.push_back(astnode("declare", - token(prefix+unsignedToDecimal(i), m), - m)); - } - // Set up variables to store the function arguments, and store the - // function ID at the byte before the start - Node datastart = astnode("add", - token("31", m), - astnode("ref", - token(prefix+"prebyte", m), - m), - m); - precompute.push_back(astnode("mstore8", - datastart, - kwargs["funid"], - m)); - for (unsigned i = 0; i < inputs.size(); i++) { - precompute.push_back(astnode("set", - token(prefix+unsignedToDecimal(i), m), - inputs[i], - m)); - - } - kwargs["datain"] = datastart; - kwargs["datainsz"] = token(unsignedToDecimal(inputs.size()*32+1), m); - } - if (!kwargs.count("outsz")) { - kwargs["dataout"] = astnode("ref", token(prefix+"dataout", m), m); - kwargs["dataoutsz"] = token("32", node.metadata); - post.push_back(astnode("get", token(prefix+"dataout", m), m)); - } - else { - kwargs["dataout"] = kwargs["out"]; - kwargs["dataoutsz"] = kwargs["outsz"]; - post.push_back(astnode("ref", token(prefix+"dataout", m), m)); - } - // Set up main call - std::vector main; - for (unsigned i = 0; i < precompute.size(); i++) { - main.push_back(precompute[i]); - } - std::vector call; - call.push_back(kwargs["gas"]); - call.push_back(kwargs["to"]); - call.push_back(kwargs["value"]); - call.push_back(kwargs["datain"]); - call.push_back(kwargs["datainsz"]); - call.push_back(kwargs["dataout"]); - call.push_back(kwargs["dataoutsz"]); - main.push_back(astnode("pop", astnode("~"+op, call, m), m)); - for (unsigned i = 0; i < post.size(); i++) { - main.push_back(post[i]); - } - Node mainNode = astnode("seq", main, node.metadata); - // Add with variables - for (int i = with.size() - 1; i >= 0; i--) { - mainNode = astnode("with", - token(with[i].first, m), - with[i].second, - mainNode, - m); - } - return mainNode; -} - -// Preprocess input containing functions -// -// localExterns is a map of the form, eg, -// -// { x: { foo: 0, bar: 1, baz: 2 }, y: { qux: 0, foo: 1 } ... } -// -// Signifying that x.foo = 0, x.baz = 2, y.foo = 1, etc -// -// globalExterns is a one-level map, eg from above -// -// { foo: 1, bar: 1, baz: 2, qux: 0 } -// -// Note that globalExterns may be ambiguous -preprocessResult preprocess(Node inp) { - inp = inp.args[0]; - Metadata m = inp.metadata; - if (inp.val != "seq") { - std::vector args; - args.push_back(inp); - inp = astnode("seq", args, m); - } - std::vector empty; - Node init = astnode("seq", empty, m); - Node shared = astnode("seq", empty, m); - std::vector any; - std::vector functions; - preprocessAux out = preprocessAux(); - out.localExterns["self"] = std::map(); - int functionCount = 0; - int storageDataCount = 0; - for (unsigned i = 0; i < inp.args.size(); i++) { - Node obj = inp.args[i]; - // Functions - if (obj.val == "def") { - if (obj.args.size() == 0) - err("Empty def", m); - std::string funName = obj.args[0].val; - // Init, shared and any are special functions - if (funName == "init" || funName == "shared" || funName == "any") { - if (obj.args[0].args.size()) - err(funName+" cannot have arguments", m); - } - if (funName == "init") init = obj.args[1]; - else if (funName == "shared") shared = obj.args[1]; - else if (funName == "any") any.push_back(obj.args[1]); - else { - // Other functions - functions.push_back(obj); - out.localExterns["self"][obj.args[0].val] = functionCount; - functionCount++; - } - } - // Extern declarations - else if (obj.val == "extern") { - std::string externName = obj.args[0].args[0].val; - Node al = obj.args[0].args[1]; - if (!out.localExterns.count(externName)) - out.localExterns[externName] = std::map(); - for (unsigned i = 0; i < al.args.size(); i++) { - out.globalExterns[al.args[i].val] = i; - out.localExterns[externName][al.args[i].val] = i; - } - } - // Storage variables/structures - else if (obj.val == "data") { - out.storageVars = getStorageVars(out.storageVars, - obj.args[0], - "", - storageDataCount); - storageDataCount += 1; - } - else any.push_back(obj); - } - std::vector main; - if (shared.args.size()) main.push_back(shared); - if (init.args.size()) main.push_back(init); - - std::vector code; - if (shared.args.size()) code.push_back(shared); - for (unsigned i = 0; i < any.size(); i++) - code.push_back(any[i]); - for (unsigned i = 0; i < functions.size(); i++) - code.push_back(functions[i]); - main.push_back(astnode("~return", - token("0", m), - astnode("lll", - astnode("seq", code, m), - token("0", m), - m), - m)); - - - - return preprocessResult(astnode("seq", main, inp.metadata), out); -} - -// Transform ".(args...)" into -// (call args...) -Node dotTransform(Node node, preprocessAux aux) { - Metadata m = node.metadata; - Node pre = node.args[0].args[0]; - std::string post = node.args[0].args[1].val; - if (node.args[0].args[1].type == ASTNODE) - err("Function name must be static", m); - // Search for as=? and call=code keywords + kwargs["gas"] = subst(parseLLL("(- (gas) 25)"), msn(), prefix, m); + // Search for as=? and call=code keywords, and isolate the actual + // function arguments + std::vector fnargs; std::string as = ""; - bool call_code = false; + std::string op = "call"; for (unsigned i = 1; i < node.args.size(); i++) { - Node arg = node.args[i]; + fnargs.push_back(node.args[i]); + Node arg = fnargs.back(); if (arg.val == "=" || arg.val == "set") { if (arg.args[0].val == "as") as = arg.args[1].val; if (arg.args[0].val == "call" && arg.args[1].val == "code") - call_code = true; + op = "callcode"; + if (arg.args[0].val == "gas") + kwargs["gas"] = arg.args[1]; + if (arg.args[0].val == "value") + kwargs["value"] = arg.args[1]; + if (arg.args[0].val == "outsz") + kwargs["outsz"] = arg.args[1]; } } - if (pre.val == "self") { + if (dotOwner.val == "self") { if (as.size()) err("Cannot use \"as\" when calling self!", m); - as = pre.val; + as = dotOwner.val; } - std::vector args; - args.push_back(pre); - // Determine the funId assuming the "as" keyword was used + // Determine the funId and sig assuming the "as" keyword was used + int funId = 0; + std::string sig; if (as.size() > 0 && aux.localExterns.count(as)) { - if (!aux.localExterns[as].count(post)) - err("Invalid call: "+printSimple(pre)+"."+post, m); - std::string funid = unsignedToDecimal(aux.localExterns[as][post]); - args.push_back(token(funid, m)); + if (!aux.localExterns[as].count(dotMember)) + err("Invalid call: "+printSimple(dotOwner)+"."+dotMember, m); + funId = aux.localExterns[as][dotMember]; + sig = aux.localExternSigs[as][dotMember]; } - // Determine the funId otherwise + // Determine the funId and sig otherwise else if (!as.size()) { - if (!aux.globalExterns.count(post)) - err("Invalid call: "+printSimple(pre)+"."+post, m); - std::string key = unsignedToDecimal(aux.globalExterns[post]); - args.push_back(token(key, m)); + if (!aux.globalExterns.count(dotMember)) + err("Invalid call: "+printSimple(dotOwner)+"."+dotMember, m); + std::string key = unsignedToDecimal(aux.globalExterns[dotMember]); + funId = aux.globalExterns[dotMember]; + sig = aux.globalExternSigs[dotMember]; + } + else err("Invalid call: "+printSimple(dotOwner)+"."+dotMember, m); + // Pack arguments + kwargs["data"] = packArguments(fnargs, sig, funId, m); + kwargs["to"] = dotOwner; + Node main; + // Pack output + if (!kwargs.count("outsz")) { + main = parseLLL( + "(with _data $data (seq " + "(pop (~"+op+" $gas $to $value (access _data 0) (access _data 1) (ref $dataout) 32))" + "(get $dataout)))"); + } + else { + main = parseLLL( + "(with _data $data (with _outsz (mul 32 $outsz) (with _out (alloc _outsz) (seq " + "(pop (~"+op+" $gas $to $value (access _data 0) (access _data 1) _out _outsz))" + "(get _out)))))"); } - else err("Invalid call: "+printSimple(pre)+"."+post, m); - for (unsigned i = 1; i < node.args.size(); i++) - args.push_back(node.args[i]); - return astnode(call_code ? "call_code" : "call", args, m); + // Set up main call + + Node o = subst(main, kwargs, prefix, m); + return o; } // Transform an access of the form self.bob, self.users[5], etc into @@ -877,7 +501,8 @@ Node dotTransform(Node node, preprocessAux aux) { // obj2[0].a -> sha3([1, 0, 0]) // obj2[5].b[1][3] -> sha3([1, 5, 1, 1, 3]) // obj2[45].c -> sha3([1, 45, 2]) -Node storageTransform(Node node, preprocessAux aux, bool mapstyle=false) { +Node storageTransform(Node node, preprocessAux aux, + bool mapstyle=false, bool ref=false) { Metadata m = node.metadata; // Get a list of all of the "access parameters" used in order // eg. self.users[5].cow[4][m[2]][woof] -> @@ -909,7 +534,7 @@ Node storageTransform(Node node, preprocessAux aux, bool mapstyle=false) { // If the size of an object exceeds 2^176, we make it an infinite // array if (decimalGt(coefficients.back(), tt176) && !mapstyle) - return storageTransform(node, aux, true); + return storageTransform(node, aux, true, ref); offset = decimalAdd(offset, aux.storageVars.offsets[tempPrefix]); c = 0; if (mapstyle) @@ -940,28 +565,29 @@ Node storageTransform(Node node, preprocessAux aux, bool mapstyle=false) { if (c > (signed)coefficients.size() - 1) { err("Too many array index lookups", m); } + Node o; if (mapstyle) { - // We pre-declare variables, relying on the idea that sequentially - // declared variables are doing to appear beside each other in - // memory - std::vector main; + std::string t = "_temp_"+mkUniqueToken(); + std::vector sub; for (unsigned i = 0; i < terms.size(); i++) - main.push_back(astnode("declare", - token(varPrefix+unsignedToDecimal(i), m), - m)); - for (unsigned i = 0; i < terms.size(); i++) - main.push_back(astnode("set", - token(varPrefix+unsignedToDecimal(i), m), - terms[i], - m)); - main.push_back(astnode("ref", token(varPrefix+"0", m), m)); - Node sz = token(unsignedToDecimal(terms.size()), m); - return astnode("sload", - astnode("sha3", - astnode("seq", main, m), - sz, - m), - m); + sub.push_back(asn("mstore", + asn("add", + tkn(utd(i * 32), m), + asn("get", tkn(t+"pos", m), m), + m), + terms[i], + m)); + sub.push_back(tkn(t+"pos", m)); + Node main = asn("with", + tkn(t+"pos", m), + asn("alloc", tkn(utd(terms.size() * 32), m), m), + asn("seq", sub, m), + m); + Node sz = token(utd(terms.size() * 32), m); + o = astnode("~sha3", + main, + sz, + m); } else { // We add up all the index*coefficients @@ -972,42 +598,92 @@ Node storageTransform(Node node, preprocessAux aux, bool mapstyle=false) { temp.push_back(terms[i]); out = astnode("add", temp, node.metadata); } - std::vector temp2; - temp2.push_back(out); - return astnode("sload", temp2, node.metadata); + o = out; + } + if (ref) return o; + else return astnode("sload", o, node.metadata); +} + +// Basic rewrite rule execution +std::pair rulesTransform(Node node, rewriteRuleSet macros) { + std::string prefix = "_temp_"+mkUniqueToken(); + bool changed = false; + if (!macros.ruleLists.count(node.val)) + return std::pair(node, false); + std::vector rules = macros.ruleLists[node.val]; + for (unsigned pos = 0; pos < rules.size(); pos++) { + rewriteRule macro = rules[pos]; + matchResult mr = match(macro.pattern, node); + if (mr.success) { + node = subst(macro.substitution, mr.map, prefix, node.metadata); + std::pair o = rulesTransform(node, macros); + o.second = true; + return o; + } + } + return std::pair(node, changed); +} + +std::pair synonymTransform(Node node) { + bool changed = false; + if (node.type == ASTNODE && synonymMap.count(node.val)) { + node.val = synonymMap[node.val]; + changed = true; } + return std::pair(node, changed); } +rewriteRuleSet nodeMacros; +rewriteRuleSet setterMacros; -// Recursively applies rewrite rules -Node apply_rules(preprocessResult pr) { +bool dontDescend(std::string s) { + return s == "macro" || s == "comment" || s == "outer"; +} + +// Recursively applies any set of rewrite rules +std::pair apply_rules_iter(preprocessResult pr, rewriteRuleSet rules) { + bool changed = false; Node node = pr.first; - // If the rewrite rules have not yet been parsed, parse them - if (!nodeMacros.size()) { - for (int i = 0; i < 9999; i++) { - std::vector o; - if (macros[i][0] == "---END---") break; - o.push_back(parseLLL(macros[i][0])); - o.push_back(parseLLL(macros[i][1])); - nodeMacros.push_back(o); + if (dontDescend(node.val)) + return std::pair(node, false); + std::pair o = rulesTransform(node, rules); + node = o.first; + changed = changed || o.second; + if (node.type == ASTNODE) { + for (unsigned i = 0; i < node.args.size(); i++) { + std::pair r = + apply_rules_iter(preprocessResult(node.args[i], pr.second), rules); + node.args[i] = r.first; + changed = changed || r.second; } } - // Assignment transformations - for (int i = 0; i < 9999; i++) { - if (setters[i][0] == "---END---") break; - if (node.val == setters[i][0]) { - node = astnode("=", - node.args[0], - astnode(setters[i][1], - node.args[0], - node.args[1], - node.metadata), - node.metadata); - } + return std::pair(node, changed); +} + +// Recursively applies rewrite rules and other primary transformations +std::pair mainTransform(preprocessResult pr) { + bool changed = false; + Node node = pr.first; + + // Anything inside "outer" should be treated as a separate program + // and thus recursively compiled in its entirety + if (node.val == "outer") { + node = apply_rules(preprocess(node.args[0])); + changed = true; } + + // Don't descend into comments, macros and inner scopes + if (dontDescend(node.val)) + return std::pair(node, changed); + // Special storage transformation if (isNodeStorageVariable(node)) { node = storageTransform(node, pr.second); + changed = true; + } + if (node.val == "ref" && isNodeStorageVariable(node.args[0])) { + node = storageTransform(node.args[0], pr.second, false, true); + changed = true; } if (node.val == "=" && isNodeStorageVariable(node.args[0])) { Node t = storageTransform(node.args[0], pr.second); @@ -1017,195 +693,213 @@ Node apply_rules(preprocessResult pr) { o.push_back(node.args[1]); node = astnode("sstore", o, node.metadata); } + changed = true; } // Main code - unsigned pos = 0; - std::string prefix = "_temp"+mkUniqueToken()+"_"; - while(1) { - if (synonyms[pos][0] == "---END---") { - break; - } - else if (node.type == ASTNODE && node.val == synonyms[pos][0]) { - node.val = synonyms[pos][1]; - } - pos++; - } - for (pos = 0; pos < nodeMacros.size(); pos++) { - Node pattern = nodeMacros[pos][0]; - matchResult mr = match(pattern, node); - if (mr.success) { - Node pattern2 = nodeMacros[pos][1]; - node = subst(pattern2, mr.map, prefix, node.metadata); - pos = 0; - } - } + std::pair pnb = synonymTransform(node); + node = pnb.first; + changed = changed || pnb.second; + // std::cerr << priority << " " << macros.size() << "\n"; + std::pair pnc = rulesTransform(node, nodeMacros); + node = pnc.first; + changed = changed || pnc.second; + + // Special transformations - if (node.val == "outer") { - pr = preprocess(node); - node = pr.first; - } - if (node.val == "array_lit") + if (node.val == "array_lit") { node = array_lit_transform(node); + changed = true; + } if (node.val == "fun" && node.args[0].val == ".") { node = dotTransform(node, pr.second); + changed = true; + } + if (node.val == "text") { + node = string_transform(node); + changed = true; } - if (node.val == "call") - node = call_transform(node, "call"); - if (node.val == "call_code") - node = call_transform(node, "call_code"); if (node.type == ASTNODE) { unsigned i = 0; + // Arg 0 of all of these is a variable, so should not be changed if (node.val == "set" || node.val == "ref" - || node.val == "get" || node.val == "with" - || node.val == "def" || node.val == "declare") { - node.args[0].val = "'" + node.args[0].val; + || node.val == "get" || node.val == "with") { + if (node.args[0].type == TOKEN && + node.args[0].val.size() > 0 && node.args[0].val[0] != '\'') { + node.args[0].val = "'" + node.args[0].val; + changed = true; + } i = 1; } - if (node.val == "def") { - for (unsigned j = 0; j < node.args[0].args.size(); j++) { - if (node.args[0].args[j].val == ":") { - node.args[0].args[j].val = "kv"; - node.args[0].args[j].args[0].val = - "'" + node.args[0].args[j].args[0].val; - } - else { - node.args[0].args[j].val = "'" + node.args[0].args[j].val; - } - } + // Convert arglen(x) to '_len_x + else if (node.val == "arglen") { + node.val = "get"; + node.args[0].val = "'_len_" + node.args[0].val; + i = 1; + changed = true; } + // Recursively process children for (; i < node.args.size(); i++) { - node.args[i] = - apply_rules(preprocessResult(node.args[i], pr.second)); + std::pair r = + mainTransform(preprocessResult(node.args[i], pr.second)); + node.args[i] = r.first; + changed = changed || r.second; } } + // Add leading ' to variable names, and wrap them inside get else if (node.type == TOKEN && !isNumberLike(node)) { - node.val = "'" + node.val; - std::vector args; - args.push_back(node); - node = astnode("get", args, node.metadata); + if (node.val.size() && node.val[0] != '\'' && node.val[0] != '$') { + Node n = astnode("get", tkn("'"+node.val), node.metadata); + node = n; + changed = true; + } } - // This allows people to use ~x as a way of having functions with the same - // name and arity as macros; the idea is that ~x is a "final" form, and - // should not be remacroed, but it is converted back at the end - if (node.type == ASTNODE && node.val[0] == '~') - node.val = node.val.substr(1); - return node; + // Convert all numbers to normalized form + else if (node.type == TOKEN && isNumberLike(node) && !isDecimal(node.val)) { + node.val = strToNumeric(node.val); + changed = true; + } + return std::pair(node, changed); } -// Compile-time arithmetic calculations -Node optimize(Node inp) { - if (inp.type == TOKEN) { - Node o = tryNumberize(inp); - if (decimalGt(o.val, tt256, true)) - err("Value too large (exceeds 32 bytes or 2^256)", inp.metadata); - return o; +// Do some preprocessing to convert all of our macro lists into compiled +// forms that can then be reused +void parseMacros() { + for (int i = 0; i < 9999; i++) { + std::vector o; + if (macros[i][0] == "---END---") break; + nodeMacros.addRule(rewriteRule( + parseLLL(macros[i][0]), + parseLLL(macros[i][1]) + )); } - for (unsigned i = 0; i < inp.args.size(); i++) { - inp.args[i] = optimize(inp.args[i]); + for (int i = 0; i < 9999; i++) { + std::vector o; + if (setters[i][0] == "---END---") break; + setterMacros.addRule(rewriteRule( + asn(setters[i][0], tkn("$x"), tkn("$y")), + asn("=", tkn("$x"), asn(setters[i][1], tkn("$x"), tkn("$y"))) + )); } - // Degenerate cases for add and mul - if (inp.args.size() == 2) { - if (inp.val == "add" && inp.args[0].type == TOKEN && - inp.args[0].val == "0") { - inp = inp.args[1]; - } - if (inp.val == "add" && inp.args[1].type == TOKEN && - inp.args[1].val == "0") { - inp = inp.args[0]; - } - if (inp.val == "mul" && inp.args[0].type == TOKEN && - inp.args[0].val == "1") { - inp = inp.args[1]; - } - if (inp.val == "mul" && inp.args[1].type == TOKEN && - inp.args[1].val == "1") { - inp = inp.args[0]; - } + for (int i = 0; i < 9999; i++) { + if (synonyms[i][0] == "---END---") break; + synonymMap[synonyms[i][0]] = synonyms[i][1]; + } +} + +Node apply_rules(preprocessResult pr) { + // If the rewrite rules have not yet been parsed, parse them + if (!nodeMacros.ruleLists.size()) parseMacros(); + // Iterate over macros by priority list + std::map::iterator it; + std::pair r; + for(it=pr.second.customMacros.begin(); + it != pr.second.customMacros.end(); it++) { + while (1) { + // std::cerr << "STARTING ARI CYCLE: " << (*it).first <<"\n"; + // std::cerr << printAST(pr.first) << "\n"; + r = apply_rules_iter(pr, (*it).second); + pr.first = r.first; + if (!r.second) break; + } + } + // Apply setter macros + while (1) { + r = apply_rules_iter(pr, setterMacros); + pr.first = r.first; + if (!r.second) break; } - // Arithmetic computation - if (inp.args.size() == 2 - && inp.args[0].type == TOKEN - && inp.args[1].type == TOKEN) { - std::string o; - if (inp.val == "add") { - o = decimalMod(decimalAdd(inp.args[0].val, inp.args[1].val), tt256); - } - else if (inp.val == "sub") { - if (decimalGt(inp.args[0].val, inp.args[1].val, true)) - o = decimalSub(inp.args[0].val, inp.args[1].val); - } - else if (inp.val == "mul") { - o = decimalMod(decimalMul(inp.args[0].val, inp.args[1].val), tt256); - } - else if (inp.val == "div" && inp.args[1].val != "0") { - o = decimalDiv(inp.args[0].val, inp.args[1].val); - } - else if (inp.val == "sdiv" && inp.args[1].val != "0" - && decimalGt(tt255, inp.args[0].val) - && decimalGt(tt255, inp.args[1].val)) { - o = decimalDiv(inp.args[0].val, inp.args[1].val); - } - else if (inp.val == "mod" && inp.args[1].val != "0") { - o = decimalMod(inp.args[0].val, inp.args[1].val); - } - else if (inp.val == "smod" && inp.args[1].val != "0" - && decimalGt(tt255, inp.args[0].val) - && decimalGt(tt255, inp.args[1].val)) { - o = decimalMod(inp.args[0].val, inp.args[1].val); - } - else if (inp.val == "exp") { - o = decimalModExp(inp.args[0].val, inp.args[1].val, tt256); - } - if (o.length()) return token(o, inp.metadata); + // Apply all other mactos + while (1) { + r = mainTransform(pr); + pr.first = r.first; + if (!r.second) break; } - return inp; + return r.first; } +// Pre-validation Node validate(Node inp) { + Metadata m = inp.metadata; if (inp.type == ASTNODE) { int i = 0; - while(valid[i][0] != "---END---") { - if (inp.val == valid[i][0]) { + while(validFunctions[i][0] != "---END---") { + if (inp.val == validFunctions[i][0]) { std::string sz = unsignedToDecimal(inp.args.size()); - if (decimalGt(valid[i][1], sz)) { + if (decimalGt(validFunctions[i][1], sz)) { err("Too few arguments for "+inp.val, inp.metadata); } - if (decimalGt(sz, valid[i][2])) { + if (decimalGt(sz, validFunctions[i][2])) { err("Too many arguments for "+inp.val, inp.metadata); } } i++; } + } + else if (inp.type == TOKEN) { + if (!inp.val.size()) err("??? empty token", m); + if (inp.val[0] == '_') err("Variables cannot start with _", m); } for (unsigned i = 0; i < inp.args.size(); i++) validate(inp.args[i]); return inp; } Node postValidate(Node inp) { + // This allows people to use ~x as a way of having functions with the same + // name and arity as macros; the idea is that ~x is a "final" form, and + // should not be remacroed, but it is converted back at the end + if (inp.val.size() > 0 && inp.val[0] == '~') { + inp.val = inp.val.substr(1); + } if (inp.type == ASTNODE) { if (inp.val == ".") err("Invalid object member (ie. a foo.bar not mapped to anything)", inp.metadata); - for (unsigned i = 0; i < inp.args.size(); i++) - postValidate(inp.args[i]); + else if (opcode(inp.val) >= 0) { + if ((signed)inp.args.size() < opinputs(inp.val)) + err("Too few arguments for "+inp.val, inp.metadata); + if ((signed)inp.args.size() > opinputs(inp.val)) + err("Too many arguments for "+inp.val, inp.metadata); + } + else if (isValidLLLFunc(inp.val, inp.args.size())) { + // do nothing + } + else err ("Invalid argument count or LLL function: "+printSimple(inp), inp.metadata); + for (unsigned i = 0; i < inp.args.size(); i++) { + inp.args[i] = postValidate(inp.args[i]); + } } return inp; } -Node outerWrap(Node inp) { - std::vector args; - args.push_back(inp); - return astnode("outer", args, inp.metadata); + +Node rewriteChunk(Node inp) { + return postValidate(optimize(apply_rules( + preprocessResult( + validate(inp), preprocessAux())))); } -Node rewrite(Node inp) { - return postValidate(optimize(apply_rules(preprocessResult( - validate(outerWrap(inp)), preprocessAux())))); +// Flatten nested sequence into flat sequence +Node flattenSeq(Node inp) { + std::vector o; + if (inp.val == "seq" && inp.type == ASTNODE) { + for (unsigned i = 0; i < inp.args.size(); i++) { + if (inp.args[i].val == "seq" && inp.args[i].type == ASTNODE) + o = extend(o, flattenSeq(inp.args[i]).args); + else + o.push_back(flattenSeq(inp.args[i])); + } + } + else if (inp.type == ASTNODE) { + for (unsigned i = 0; i < inp.args.size(); i++) { + o.push_back(flattenSeq(inp.args[i])); + } + } + else return inp; + return asn(inp.val, o, inp.metadata); } -Node rewriteChunk(Node inp) { - return postValidate(optimize(apply_rules(preprocessResult( - validate(inp), preprocessAux())))); +Node rewrite(Node inp) { + return postValidate(optimize(apply_rules(preprocess(flattenSeq(inp))))); } using namespace std; diff --git a/libserpent/tokenize.cpp b/libserpent/tokenize.cpp index c6a211593..b60cc8a44 100644 --- a/libserpent/tokenize.cpp +++ b/libserpent/tokenize.cpp @@ -13,8 +13,8 @@ int chartype(char c) { if (c >= '0' && c <= '9') return ALPHANUM; else if (c >= 'a' && c <= 'z') return ALPHANUM; else if (c >= 'A' && c <= 'Z') return ALPHANUM; - else if (std::string("~_$").find(c) != std::string::npos) return ALPHANUM; - else if (c == '\t' || c == ' ' || c == '\n') return SPACE; + else if (std::string("~_$@").find(c) != std::string::npos) return ALPHANUM; + else if (c == '\t' || c == ' ' || c == '\n' || c == '\r') return SPACE; else if (std::string("()[]{}").find(c) != std::string::npos) return BRACK; else if (c == '"') return DQUOTE; else if (c == '\'') return SQUOTE; diff --git a/libserpent/util.cpp b/libserpent/util.cpp index fbce5e8b5..5e83c0e41 100644 --- a/libserpent/util.cpp +++ b/libserpent/util.cpp @@ -2,7 +2,6 @@ #include #include #include -#include #include "util.h" #include "bignum.h" #include @@ -28,6 +27,11 @@ Node astnode(std::string val, std::vector args, Metadata met) { } //AST node constructors for a specific number of children +Node astnode(std::string val, Metadata met) { + std::vector args; + return astnode(val, args, met); +} + Node astnode(std::string val, Node a, Metadata met) { std::vector args; args.push_back(a); @@ -49,6 +53,16 @@ Node astnode(std::string val, Node a, Node b, Node c, Metadata met) { return astnode(val, args, met); } +Node astnode(std::string val, Node a, Node b, Node c, Node d, Metadata met) { + std::vector args; + args.push_back(a); + args.push_back(b); + args.push_back(c); + args.push_back(d); + return astnode(val, args, met); +} + + // Print token list std::string printTokens(std::vector tokens) { std::string s = ""; @@ -146,6 +160,15 @@ std::string indentLines(std::string inp) { return joinLines(lines); } +// Binary to hexadecimal +std::string binToNumeric(std::string inp) { + std::string o = "0"; + for (unsigned i = 0; i < inp.length(); i++) { + o = decimalAdd(decimalMul(o,"256"), unsignedToDecimal((unsigned char)inp[i])); + } + return o; +} + // Converts string to simple numeric format std::string strToNumeric(std::string inp) { std::string o = "0"; @@ -154,7 +177,7 @@ std::string strToNumeric(std::string inp) { } else if ((inp[0] == '"' && inp[inp.length()-1] == '"') || (inp[0] == '\'' && inp[inp.length()-1] == '\'')) { - for (unsigned i = 1; i < inp.length() - 1; i++) { + for (unsigned i = 1; i < inp.length() - 1; i++) { o = decimalAdd(decimalMul(o,"256"), unsignedToDecimal((unsigned char)inp[i])); } } @@ -181,6 +204,14 @@ bool isNumberLike(Node node) { return strToNumeric(node.val) != ""; } +// Is the number decimal? +bool isDecimal(std::string inp) { + for (unsigned i = 0; i < inp.length(); i++) { + if (inp[i] < '0' || inp[i] > '9') return false; + } + return true; +} + //Normalizes number representations Node nodeToNumeric(Node node) { std::string o = strToNumeric(node.val); @@ -246,6 +277,14 @@ void err(std::string errtext, Metadata met) { throw(err); } +//Report warning +void warn(std::string errtext, Metadata met) { + std::string err = "Warning (file \"" + met.file + "\", line " + + unsignedToDecimal(met.ln + 1) + ", char " + unsignedToDecimal(met.ch) + + "): " + errtext; + std::cerr << err << "\n"; +} + //Bin to hex std::string binToHex(std::string inp) { std::string o = ""; @@ -280,7 +319,15 @@ std::string upperCase(std::string inp) { //Three-int vector std::vector triple(int a, int b, int c) { - std::vector o; - o.push_back(a); o.push_back(b); o.push_back(c); - return o; + std::vector v; + v.push_back(a); + v.push_back(b); + v.push_back(c); + return v; +} + +//Extend node vector +std::vector extend(std::vector a, std::vector b) { + for (unsigned i = 0; i < b.size(); i++) a.push_back(b[i]); + return a; } diff --git a/libserpent/util.h b/libserpent/util.h index c0a2e9324..e25712d0f 100644 --- a/libserpent/util.h +++ b/libserpent/util.h @@ -28,30 +28,36 @@ const int TOKEN = 0, // Stores metadata about each token class Metadata { public: - Metadata(std::string File="main", int Ln=0, int Ch=0) { + Metadata(std::string File="main", int Ln=-1, int Ch=-1) { file = File; ln = Ln; ch = Ch; + fixed = false; } std::string file; int ln; int ch; + bool fixed; }; std::string mkUniqueToken(); // type can be TOKEN or ASTNODE -struct Node { - int type; - std::string val; - std::vector args; - Metadata metadata; +class Node { + public: + int type; + std::string val; + std::vector args; + Metadata metadata; }; Node token(std::string val, Metadata met=Metadata()); Node astnode(std::string val, std::vector args, Metadata met=Metadata()); +Node astnode(std::string val, Metadata met=Metadata()); Node astnode(std::string val, Node a, Metadata met=Metadata()); Node astnode(std::string val, Node a, Node b, Metadata met=Metadata()); Node astnode(std::string val, Node a, Node b, Node c, Metadata met=Metadata()); +Node astnode(std::string val, Node a, Node b, + Node c, Node d, Metadata met=Metadata()); // Number of tokens in a tree int treeSize(Node prog); @@ -74,6 +80,9 @@ std::string joinLines(std::vector lines); // Indent all lines by 4 spaces std::string indentLines(std::string inp); +// Converts binary to simple numeric format +std::string binToNumeric(std::string inp); + // Converts string to simple numeric format std::string strToNumeric(std::string inp); @@ -98,6 +107,9 @@ bool exists(std::string fileName); //Report error void err(std::string errtext, Metadata met); +//Report warning +void warn(std::string errtext, Metadata met); + //Bin to hex std::string binToHex(std::string inp); @@ -110,4 +122,16 @@ std::string upperCase(std::string inp); //Three-int vector std::vector triple(int a, int b, int c); +//Extend node vector +std::vector extend(std::vector a, std::vector b); + +// Is the number decimal? +bool isDecimal(std::string inp); + +#define asn astnode +#define tkn token +#define msi std::map +#define msn std::map +#define mss std::map + #endif diff --git a/sc/cmdline.cpp b/sc/cmdline.cpp index b44d2538c..a5fed37d6 100644 --- a/sc/cmdline.cpp +++ b/sc/cmdline.cpp @@ -10,6 +10,19 @@ int main(int argv, char** argc) { std::cerr << "Must provide a command and arguments! Try parse, rewrite, compile, assemble\n"; return 0; } + if (argv == 2 && (std::string(argc[1]) == "--help" || std::string(argc[1]) == "-h" )) { + std::cout << argc[1] << "\n"; + + std::cout << "serpent command input\n"; + std::cout << "where input -s for from stdin, a file, or interpreted as serpent code if does not exist as file."; + std::cout << "where command: \n"; + std::cout << " parse: Just parses and returns s-expression code.\n"; + std::cout << " rewrite: Parse, use rewrite rules print s-expressions of result.\n"; + std::cout << " compile: Return resulting compiled EVM code in hex.\n"; + std::cout << " assemble: Return result from step before compilation.\n"; + return 0; + } + std::string flag = ""; std::string command = argc[1]; std::string input; From c4ed74cc8ba923a2c15ac4f4e04962df5eec3727 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 18 Dec 2014 16:27:07 +0100 Subject: [PATCH 263/277] Additional serpent files. --- libserpent/functions.cpp | 203 ++++++++++++++++++++++ libserpent/functions.h | 39 +++++ libserpent/opcodes.cpp | 154 +++++++++++++++++ libserpent/optimize.cpp | 98 +++++++++++ libserpent/optimize.h | 19 +++ libserpent/preprocess.cpp | 327 ++++++++++++++++++++++++++++++++++++ libserpent/preprocess.h | 50 ++++++ libserpent/rewriteutils.cpp | 211 +++++++++++++++++++++++ libserpent/rewriteutils.h | 76 +++++++++ 9 files changed, 1177 insertions(+) create mode 100644 libserpent/functions.cpp create mode 100644 libserpent/functions.h create mode 100644 libserpent/opcodes.cpp create mode 100644 libserpent/optimize.cpp create mode 100644 libserpent/optimize.h create mode 100644 libserpent/preprocess.cpp create mode 100644 libserpent/preprocess.h create mode 100644 libserpent/rewriteutils.cpp create mode 100644 libserpent/rewriteutils.h diff --git a/libserpent/functions.cpp b/libserpent/functions.cpp new file mode 100644 index 000000000..78e12e84a --- /dev/null +++ b/libserpent/functions.cpp @@ -0,0 +1,203 @@ +#include +#include +#include +#include +#include "util.h" +#include "lllparser.h" +#include "bignum.h" +#include "optimize.h" +#include "rewriteutils.h" +#include "preprocess.h" +#include "functions.h" + +std::string getSignature(std::vector args) { + std::string o; + for (unsigned i = 0; i < args.size(); i++) { + if (args[i].val == ":" && args[i].args[1].val == "s") + o += "s"; + else if (args[i].val == ":" && args[i].args[1].val == "a") + o += "a"; + else + o += "i"; + } + return o; +} + +// Convert a list of arguments into a node containing a +// < datastart, datasz > pair + +Node packArguments(std::vector args, std::string sig, + int funId, Metadata m) { + // Plain old 32 byte arguments + std::vector nargs; + // Variable-sized arguments + std::vector vargs; + // Variable sizes + std::vector sizes; + // Is a variable an array? + std::vector isArray; + // Fill up above three argument lists + int argCount = 0; + for (unsigned i = 0; i < args.size(); i++) { + Metadata m = args[i].metadata; + if (args[i].val == "=") { + // do nothing + } + else { + // Determine the correct argument type + char argType; + if (sig.size() > 0) { + if (argCount >= (signed)sig.size()) + err("Too many args", m); + argType = sig[argCount]; + } + else argType = 'i'; + // Integer (also usable for short strings) + if (argType == 'i') { + if (args[i].val == ":") + err("Function asks for int, provided string or array", m); + nargs.push_back(args[i]); + } + // Long string + else if (argType == 's') { + if (args[i].val != ":") + err("Must specify string length", m); + vargs.push_back(args[i].args[0]); + sizes.push_back(args[i].args[1]); + isArray.push_back(false); + } + // Array + else if (argType == 'a') { + if (args[i].val != ":") + err("Must specify array length", m); + vargs.push_back(args[i].args[0]); + sizes.push_back(args[i].args[1]); + isArray.push_back(true); + } + else err("Invalid arg type in signature", m); + argCount++; + } + } + int static_arg_size = 1 + (vargs.size() + nargs.size()) * 32; + // Start off by saving the size variables and calculating the total + msn kwargs; + kwargs["funid"] = tkn(utd(funId), m); + std::string pattern = + "(with _sztot "+utd(static_arg_size)+" " + " (with _sizes (alloc "+utd(sizes.size() * 32)+") " + " (seq "; + for (unsigned i = 0; i < sizes.size(); i++) { + std::string sizeIncrement = + isArray[i] ? "(mul 32 _x)" : "_x"; + pattern += + "(with _x $sz"+utd(i)+"(seq " + " (mstore (add _sizes "+utd(i * 32)+") _x) " + " (set _sztot (add _sztot "+sizeIncrement+" )))) "; + kwargs["sz"+utd(i)] = sizes[i]; + } + // Allocate memory, and set first data byte + pattern += + "(with _datastart (alloc (add _sztot 32)) (seq " + " (mstore8 _datastart $funid) "; + // Copy over size variables + for (unsigned i = 0; i < sizes.size(); i++) { + int v = 1 + i * 32; + pattern += + " (mstore " + " (add _datastart "+utd(v)+") " + " (mload (add _sizes "+utd(v-1)+"))) "; + } + // Store normal arguments + for (unsigned i = 0; i < nargs.size(); i++) { + int v = 1 + (i + sizes.size()) * 32; + pattern += + " (mstore (add _datastart "+utd(v)+") $"+utd(i)+") "; + kwargs[utd(i)] = nargs[i]; + } + // Loop through variable-sized arguments, store them + pattern += + " (with _pos (add _datastart "+utd(static_arg_size)+") (seq"; + for (unsigned i = 0; i < vargs.size(); i++) { + std::string copySize = + isArray[i] ? "(mul 32 (mload (add _sizes "+utd(i * 32)+")))" + : "(mload (add _sizes "+utd(i * 32)+"))"; + pattern += + " (unsafe_mcopy _pos $vl"+utd(i)+" "+copySize+") " + " (set _pos (add _pos "+copySize+")) "; + kwargs["vl"+utd(i)] = vargs[i]; + } + // Return a 2-item array containing the start and size + pattern += " (array_lit _datastart _sztot))))))))"; + std::string prefix = "_temp_"+mkUniqueToken(); + // Fill in pattern, return triple + return subst(parseLLL(pattern), kwargs, prefix, m); +} + +// Create a node for argument unpacking +Node unpackArguments(std::vector vars, Metadata m) { + std::vector varNames; + std::vector longVarNames; + std::vector longVarIsArray; + // Fill in variable and long variable names, as well as which + // long variables are arrays and which are strings + for (unsigned i = 0; i < vars.size(); i++) { + if (vars[i].val == ":") { + if (vars[i].args.size() != 2) + err("Malformed def!", m); + longVarNames.push_back(vars[i].args[0].val); + std::string tag = vars[i].args[1].val; + if (tag == "s") + longVarIsArray.push_back(false); + else if (tag == "a") + longVarIsArray.push_back(true); + else + err("Function value can only be string or array", m); + } + else { + varNames.push_back(vars[i].val); + } + } + std::vector sub; + if (!varNames.size() && !longVarNames.size()) { + // do nothing if we have no arguments + } + else { + std::vector varNodes; + for (unsigned i = 0; i < longVarNames.size(); i++) + varNodes.push_back(token(longVarNames[i], m)); + for (unsigned i = 0; i < varNames.size(); i++) + varNodes.push_back(token(varNames[i], m)); + // Copy over variable lengths and short variables + for (unsigned i = 0; i < varNodes.size(); i++) { + int pos = 1 + i * 32; + std::string prefix = (i < longVarNames.size()) ? "_len_" : ""; + sub.push_back(asn("untyped", asn("set", + token(prefix+varNodes[i].val, m), + asn("calldataload", tkn(utd(pos), m), m), + m))); + } + // Copy over long variables + if (longVarNames.size() > 0) { + std::vector sub2; + int pos = varNodes.size() * 32 + 1; + Node tot = tkn("_tot", m); + for (unsigned i = 0; i < longVarNames.size(); i++) { + Node var = tkn(longVarNames[i], m); + Node varlen = longVarIsArray[i] + ? asn("mul", tkn("32", m), tkn("_len_"+longVarNames[i], m)) + : tkn("_len_"+longVarNames[i], m); + sub2.push_back(asn("untyped", + asn("set", var, asn("alloc", varlen)))); + sub2.push_back(asn("calldatacopy", var, tot, varlen)); + sub2.push_back(asn("set", tot, asn("add", tot, varlen))); + } + std::string prefix = "_temp_"+mkUniqueToken(); + sub.push_back(subst( + astnode("with", tot, tkn(utd(pos), m), asn("seq", sub2)), + msn(), + prefix, + m)); + } + } + return asn("seq", sub, m); +} diff --git a/libserpent/functions.h b/libserpent/functions.h new file mode 100644 index 000000000..68a1c69ce --- /dev/null +++ b/libserpent/functions.h @@ -0,0 +1,39 @@ +#ifndef ETHSERP_FUNCTIONS +#define ETHSERP_FUNCTIONS + +#include +#include +#include +#include +#include "util.h" +#include "lllparser.h" +#include "bignum.h" +#include "optimize.h" +#include "rewriteutils.h" +#include "preprocess.h" + + +class argPack { + public: + argPack(Node a, Node b, Node c) { + pre = a; + datastart = b; + datasz = c; + } + Node pre; + Node datastart; + Node datasz; +}; + +// Get a signature from a function +std::string getSignature(std::vector args); + +// Convert a list of arguments into a node +// triple, given the signature of a function +Node packArguments(std::vector args, std::string sig, + int funId, Metadata m); + +// Create a node for argument unpacking +Node unpackArguments(std::vector vars, Metadata m); + +#endif diff --git a/libserpent/opcodes.cpp b/libserpent/opcodes.cpp new file mode 100644 index 000000000..b24144e46 --- /dev/null +++ b/libserpent/opcodes.cpp @@ -0,0 +1,154 @@ +#include +#include +#include +#include +#include "opcodes.h" +#include "util.h" +#include "bignum.h" + +Mapping mapping[] = { + Mapping("STOP", 0x00, 0, 0), + Mapping("ADD", 0x01, 2, 1), + Mapping("MUL", 0x02, 2, 1), + Mapping("SUB", 0x03, 2, 1), + Mapping("DIV", 0x04, 2, 1), + Mapping("SDIV", 0x05, 2, 1), + Mapping("MOD", 0x06, 2, 1), + Mapping("SMOD", 0x07, 2, 1), + Mapping("ADDMOD", 0x08, 3, 1), + Mapping("MULMOD", 0x09, 3, 1), + Mapping("EXP", 0x0a, 2, 1), + Mapping("SIGNEXTEND", 0x0b, 2, 1), + Mapping("LT", 0x10, 2, 1), + Mapping("GT", 0x11, 2, 1), + Mapping("SLT", 0x12, 2, 1), + Mapping("SGT", 0x13, 2, 1), + Mapping("EQ", 0x14, 2, 1), + Mapping("ISZERO", 0x15, 1, 1), + Mapping("AND", 0x16, 2, 1), + Mapping("OR", 0x17, 2, 1), + Mapping("XOR", 0x18, 2, 1), + Mapping("NOT", 0x19, 1, 1), + Mapping("BYTE", 0x1a, 2, 1), + Mapping("SHA3", 0x20, 2, 1), + Mapping("ADDRESS", 0x30, 0, 1), + Mapping("BALANCE", 0x31, 1, 1), + Mapping("ORIGIN", 0x32, 0, 1), + Mapping("CALLER", 0x33, 0, 1), + Mapping("CALLVALUE", 0x34, 0, 1), + Mapping("CALLDATALOAD", 0x35, 1, 1), + Mapping("CALLDATASIZE", 0x36, 0, 1), + Mapping("CALLDATACOPY", 0x37, 3, 0), + Mapping("CODESIZE", 0x38, 0, 1), + Mapping("CODECOPY", 0x39, 3, 0), + Mapping("GASPRICE", 0x3a, 0, 1), + Mapping("EXTCODESIZE", 0x3b, 1, 1), + Mapping("EXTCODECOPY", 0x3c, 4, 0), + Mapping("PREVHASH", 0x40, 0, 1), + Mapping("COINBASE", 0x41, 0, 1), + Mapping("TIMESTAMP", 0x42, 0, 1), + Mapping("NUMBER", 0x43, 0, 1), + Mapping("DIFFICULTY", 0x44, 0, 1), + Mapping("GASLIMIT", 0x45, 0, 1), + Mapping("POP", 0x50, 1, 0), + Mapping("MLOAD", 0x51, 1, 1), + Mapping("MSTORE", 0x52, 2, 0), + Mapping("MSTORE8", 0x53, 2, 0), + Mapping("SLOAD", 0x54, 1, 1), + Mapping("SSTORE", 0x55, 2, 0), + Mapping("JUMP", 0x56, 1, 0), + Mapping("JUMPI", 0x57, 2, 0), + Mapping("PC", 0x58, 0, 1), + Mapping("MSIZE", 0x59, 0, 1), + Mapping("GAS", 0x5a, 0, 1), + Mapping("JUMPDEST", 0x5b, 0, 0), + Mapping("LOG0", 0xa0, 2, 0), + Mapping("LOG1", 0xa1, 3, 0), + Mapping("LOG2", 0xa2, 4, 0), + Mapping("LOG3", 0xa3, 5, 0), + Mapping("LOG4", 0xa4, 6, 0), + Mapping("CREATE", 0xf0, 3, 1), + Mapping("CALL", 0xf1, 7, 1), + Mapping("CALLCODE", 0xf2, 7, 1), + Mapping("RETURN", 0xf3, 2, 0), + Mapping("SUICIDE", 0xff, 1, 0), + Mapping("---END---", 0x00, 0, 0), +}; + +std::map > opcodes; +std::map reverseOpcodes; + +// Fetches everything EXCEPT PUSH1..32 +std::pair > _opdata(std::string ops, int opi) { + if (!opcodes.size()) { + int i = 0; + while (mapping[i].op != "---END---") { + Mapping mi = mapping[i]; + opcodes[mi.op] = triple(mi.opcode, mi.in, mi.out); + i++; + } + for (i = 1; i <= 16; i++) { + opcodes["DUP"+unsignedToDecimal(i)] = triple(0x7f + i, i, i+1); + opcodes["SWAP"+unsignedToDecimal(i)] = triple(0x8f + i, i+1, i+1); + } + for (std::map >::iterator it=opcodes.begin(); + it != opcodes.end(); + it++) { + reverseOpcodes[(*it).second[0]] = (*it).first; + } + } + ops = upperCase(ops); + std::string op; + std::vector opdata; + op = reverseOpcodes.count(opi) ? reverseOpcodes[opi] : ""; + opdata = opcodes.count(ops) ? opcodes[ops] : triple(-1, -1, -1); + return std::pair >(op, opdata); +} + +int opcode(std::string op) { + return _opdata(op, -1).second[0]; +} + +int opinputs(std::string op) { + return _opdata(op, -1).second[1]; +} + +int opoutputs(std::string op) { + return _opdata(op, -1).second[2]; +} + +std::string op(int opcode) { + return _opdata("", opcode).first; +} + +std::string lllSpecials[][3] = { + { "ref", "1", "1" }, + { "get", "1", "1" }, + { "set", "2", "2" }, + { "with", "3", "3" }, + { "comment", "0", "2147483647" }, + { "ops", "0", "2147483647" }, + { "lll", "2", "2" }, + { "seq", "0", "2147483647" }, + { "if", "3", "3" }, + { "unless", "2", "2" }, + { "until", "2", "2" }, + { "alloc", "1", "1" }, + { "---END---", "0", "0" }, +}; + +std::map > lllMap; + +// Is a function name one of the valid functions above? +bool isValidLLLFunc(std::string f, int argc) { + if (lllMap.size() == 0) { + for (int i = 0; ; i++) { + if (lllSpecials[i][0] == "---END---") break; + lllMap[lllSpecials[i][0]] = std::pair( + dtu(lllSpecials[i][1]), dtu(lllSpecials[i][2])); + } + } + return lllMap.count(f) + && argc >= lllMap[f].first + && argc <= lllMap[f].second; +} diff --git a/libserpent/optimize.cpp b/libserpent/optimize.cpp new file mode 100644 index 000000000..e689fcb69 --- /dev/null +++ b/libserpent/optimize.cpp @@ -0,0 +1,98 @@ +#include +#include +#include +#include +#include "util.h" +#include "lllparser.h" +#include "bignum.h" + +// Compile-time arithmetic calculations +Node optimize(Node inp) { + if (inp.type == TOKEN) { + Node o = tryNumberize(inp); + if (decimalGt(o.val, tt256, true)) + err("Value too large (exceeds 32 bytes or 2^256)", inp.metadata); + return o; + } + for (unsigned i = 0; i < inp.args.size(); i++) { + inp.args[i] = optimize(inp.args[i]); + } + // Arithmetic-specific transform + if (inp.val == "+") inp.val = "add"; + if (inp.val == "*") inp.val = "mul"; + if (inp.val == "-") inp.val = "sub"; + if (inp.val == "/") inp.val = "sdiv"; + if (inp.val == "^") inp.val = "exp"; + if (inp.val == "**") inp.val = "exp"; + if (inp.val == "%") inp.val = "smod"; + // Degenerate cases for add and mul + if (inp.args.size() == 2) { + if (inp.val == "add" && inp.args[0].type == TOKEN && + inp.args[0].val == "0") { + Node x = inp.args[1]; + inp = x; + } + if (inp.val == "add" && inp.args[1].type == TOKEN && + inp.args[1].val == "0") { + Node x = inp.args[0]; + inp = x; + } + if (inp.val == "mul" && inp.args[0].type == TOKEN && + inp.args[0].val == "1") { + Node x = inp.args[1]; + inp = x; + } + if (inp.val == "mul" && inp.args[1].type == TOKEN && + inp.args[1].val == "1") { + Node x = inp.args[0]; + inp = x; + } + } + // Arithmetic computation + if (inp.args.size() == 2 + && inp.args[0].type == TOKEN + && inp.args[1].type == TOKEN) { + std::string o; + if (inp.val == "add") { + o = decimalMod(decimalAdd(inp.args[0].val, inp.args[1].val), tt256); + } + else if (inp.val == "sub") { + if (decimalGt(inp.args[0].val, inp.args[1].val, true)) + o = decimalSub(inp.args[0].val, inp.args[1].val); + } + else if (inp.val == "mul") { + o = decimalMod(decimalMul(inp.args[0].val, inp.args[1].val), tt256); + } + else if (inp.val == "div" && inp.args[1].val != "0") { + o = decimalDiv(inp.args[0].val, inp.args[1].val); + } + else if (inp.val == "sdiv" && inp.args[1].val != "0" + && decimalGt(tt255, inp.args[0].val) + && decimalGt(tt255, inp.args[1].val)) { + o = decimalDiv(inp.args[0].val, inp.args[1].val); + } + else if (inp.val == "mod" && inp.args[1].val != "0") { + o = decimalMod(inp.args[0].val, inp.args[1].val); + } + else if (inp.val == "smod" && inp.args[1].val != "0" + && decimalGt(tt255, inp.args[0].val) + && decimalGt(tt255, inp.args[1].val)) { + o = decimalMod(inp.args[0].val, inp.args[1].val); + } + else if (inp.val == "exp") { + o = decimalModExp(inp.args[0].val, inp.args[1].val, tt256); + } + if (o.length()) return token(o, inp.metadata); + } + return inp; +} + +// Is a node degenerate (ie. trivial to calculate) ? +bool isDegenerate(Node n) { + return optimize(n).type == TOKEN; +} + +// Is a node purely arithmetic? +bool isPureArithmetic(Node n) { + return isNumberLike(optimize(n)); +} diff --git a/libserpent/optimize.h b/libserpent/optimize.h new file mode 100644 index 000000000..06ea3bba1 --- /dev/null +++ b/libserpent/optimize.h @@ -0,0 +1,19 @@ +#ifndef ETHSERP_OPTIMIZER +#define ETHSERP_OPTIMIZER + +#include +#include +#include +#include +#include "util.h" + +// Compile-time arithmetic calculations +Node optimize(Node inp); + +// Is a node degenerate (ie. trivial to calculate) ? +bool isDegenerate(Node n); + +// Is a node purely arithmetic? +bool isPureArithmetic(Node n); + +#endif diff --git a/libserpent/preprocess.cpp b/libserpent/preprocess.cpp new file mode 100644 index 000000000..2df149945 --- /dev/null +++ b/libserpent/preprocess.cpp @@ -0,0 +1,327 @@ +#include +#include +#include +#include +#include "util.h" +#include "lllparser.h" +#include "bignum.h" +#include "rewriteutils.h" +#include "optimize.h" +#include "preprocess.h" +#include "functions.h" +#include "opcodes.h" + +// Convert a function of the form (def (f x y z) (do stuff)) into +// (if (first byte of ABI is correct) (seq (setup x y z) (do stuff))) +Node convFunction(Node node, int functionCount) { + std::string prefix = "_temp"+mkUniqueToken()+"_"; + Metadata m = node.metadata; + + if (node.args.size() != 2) + err("Malformed def!", m); + // Collect the list of variable names and variable byte counts + Node unpack = unpackArguments(node.args[0].args, m); + // And the actual code + Node body = node.args[1]; + // Main LLL-based function body + return astnode("if", + astnode("eq", + astnode("get", token("__funid", m), m), + token(unsignedToDecimal(functionCount), m), + m), + astnode("seq", unpack, body, m)); +} + +// Populate an svObj with the arguments needed to determine +// the storage position of a node +svObj getStorageVars(svObj pre, Node node, std::string prefix, + int index) { + Metadata m = node.metadata; + if (!pre.globalOffset.size()) pre.globalOffset = "0"; + std::vector h; + std::vector coefficients; + // Array accesses or atoms + if (node.val == "access" || node.type == TOKEN) { + std::string tot = "1"; + h = listfyStorageAccess(node); + coefficients.push_back("1"); + for (unsigned i = h.size() - 1; i >= 1; i--) { + // Array sizes must be constant or at least arithmetically + // evaluable at compile time + if (!isPureArithmetic(h[i])) + err("Array size must be fixed value", m); + // Create a list of the coefficient associated with each + // array index + coefficients.push_back(decimalMul(coefficients.back(), h[i].val)); + } + } + // Tuples + else { + int startc; + // Handle the (fun args...) case + if (node.val == "fun") { + startc = 1; + h = listfyStorageAccess(node.args[0]); + } + // Handle the ( args...) case, which + // the serpent parser produces when the function + // is a simple name and not a complex astnode + else { + startc = 0; + h = listfyStorageAccess(token(node.val, m)); + } + svObj sub = pre; + sub.globalOffset = "0"; + // Evaluate tuple elements recursively + for (unsigned i = startc; i < node.args.size(); i++) { + sub = getStorageVars(sub, + node.args[i], + prefix+h[0].val.substr(2)+".", + i-startc); + } + coefficients.push_back(sub.globalOffset); + for (unsigned i = h.size() - 1; i >= 1; i--) { + // Array sizes must be constant or at least arithmetically + // evaluable at compile time + if (!isPureArithmetic(h[i])) + err("Array size must be fixed value", m); + // Create a list of the coefficient associated with each + // array index + coefficients.push_back(decimalMul(coefficients.back(), h[i].val)); + } + pre.offsets = sub.offsets; + pre.coefficients = sub.coefficients; + pre.nonfinal = sub.nonfinal; + pre.nonfinal[prefix+h[0].val.substr(2)] = true; + } + pre.coefficients[prefix+h[0].val.substr(2)] = coefficients; + pre.offsets[prefix+h[0].val.substr(2)] = pre.globalOffset; + pre.indices[prefix+h[0].val.substr(2)] = index; + if (decimalGt(tt176, coefficients.back())) + pre.globalOffset = decimalAdd(pre.globalOffset, coefficients.back()); + return pre; +} + +// Preprocess input containing functions +// +// localExterns is a map of the form, eg, +// +// { x: { foo: 0, bar: 1, baz: 2 }, y: { qux: 0, foo: 1 } ... } +// +// localExternSigs is a map of the form, eg, +// +// { x : { foo: iii, bar: iis, baz: ia }, y: { qux: i, foo: as } ... } +// +// Signifying that x.foo = 0, x.baz = 2, y.foo = 1, etc +// and that x.foo has three integers as arguments, x.bar has two +// integers and a variable-length string, and baz has an integer +// and an array +// +// globalExterns is a one-level map, eg from above +// +// { foo: 1, bar: 1, baz: 2, qux: 0 } +// +// globalExternSigs is a one-level map, eg from above +// +// { foo: as, bar: iis, baz: ia, qux: i} +// +// Note that globalExterns and globalExternSigs may be ambiguous +// Also, a null signature implies an infinite tail of integers +preprocessResult preprocessInit(Node inp) { + Metadata m = inp.metadata; + if (inp.val != "seq") + inp = astnode("seq", inp, m); + std::vector empty = std::vector(); + Node init = astnode("seq", empty, m); + Node shared = astnode("seq", empty, m); + std::vector any; + std::vector functions; + preprocessAux out = preprocessAux(); + out.localExterns["self"] = std::map(); + int functionCount = 0; + int storageDataCount = 0; + for (unsigned i = 0; i < inp.args.size(); i++) { + Node obj = inp.args[i]; + // Functions + if (obj.val == "def") { + if (obj.args.size() == 0) + err("Empty def", m); + std::string funName = obj.args[0].val; + // Init, shared and any are special functions + if (funName == "init" || funName == "shared" || funName == "any") { + if (obj.args[0].args.size()) + err(funName+" cannot have arguments", m); + } + if (funName == "init") init = obj.args[1]; + else if (funName == "shared") shared = obj.args[1]; + else if (funName == "any") any.push_back(obj.args[1]); + else { + // Other functions + functions.push_back(convFunction(obj, functionCount)); + out.localExterns["self"][obj.args[0].val] = functionCount; + out.localExternSigs["self"][obj.args[0].val] + = getSignature(obj.args[0].args); + functionCount++; + } + } + // Extern declarations + else if (obj.val == "extern") { + std::string externName = obj.args[0].val; + Node al = obj.args[1]; + if (!out.localExterns.count(externName)) + out.localExterns[externName] = std::map(); + for (unsigned i = 0; i < al.args.size(); i++) { + if (al.args[i].val == ":") { + std::string v = al.args[i].args[0].val; + std::string sig = al.args[i].args[1].val; + out.globalExterns[v] = i; + out.globalExternSigs[v] = sig; + out.localExterns[externName][v] = i; + out.localExternSigs[externName][v] = sig; + } + else { + std::string v = al.args[i].val; + out.globalExterns[v] = i; + out.globalExternSigs[v] = ""; + out.localExterns[externName][v] = i; + out.localExternSigs[externName][v] = ""; + } + } + } + // Custom macros + else if (obj.val == "macro" || (obj.val == "fun" && obj.args[0].val == "macro")) { + // Rules for valid macros: + // + // There are only four categories of valid macros: + // + // 1. a macro where the outer function is something + // which is NOT an existing valid function/extern/datum + // 2. a macro of the form set(c(x), d) where c must NOT + // be an existing valid function/extern/datum + // 3. something of the form access(c(x)), where c must NOT + // be an existing valid function/extern/datum + // 4. something of the form set(access(c(x)), d) where c must + // NOT be an existing valid function/extern/datum + // 5. something of the form with(c(x), d, e) where c must + // NOT be an existing valid function/extern/datum + bool valid = false; + Node pattern; + Node substitution; + int priority; + // Priority not set: default zero + if (obj.val == "macro") { + pattern = obj.args[0]; + substitution = obj.args[1]; + priority = 0; + } + // Specified priority + else { + pattern = obj.args[1]; + substitution = obj.args[2]; + if (obj.args[0].args.size()) + priority = dtu(obj.args[0].args[0].val); + else + priority = 0; + } + if (opcode(pattern.val) < 0 && !isValidFunctionName(pattern.val)) + valid = true; + if (pattern.val == "set" && + opcode(pattern.args[0].val) < 0 && + !isValidFunctionName(pattern.args[0].val)) + valid = true; + if (pattern.val == "access" && + opcode(pattern.args[0].val) < 0 && + !isValidFunctionName(pattern.args[0].val)) + if (pattern.val == "set" && + pattern.args[0].val == "access" && + opcode(pattern.args[0].args[0].val) < 0 && + !isValidFunctionName(pattern.args[0].args[0].val)) + valid = true; + if (pattern.val == "with" && + opcode(pattern.args[0].val) < 0 && + !isValidFunctionName(pattern.args[0].val)) + valid = true; + if (valid) { + if (!out.customMacros.count(priority)) + out.customMacros[priority] = rewriteRuleSet(); + out.customMacros[priority].addRule + (rewriteRule(pattern, substitution)); + } + else warn("Macro does not fit valid template: "+printSimple(pattern), m); + } + // Variable types + else if (obj.val == "type") { + std::string typeName = obj.args[0].val; + std::vector vars = obj.args[1].args; + for (unsigned i = 0; i < vars.size(); i++) + out.types[vars[i].val] = typeName; + } + // Storage variables/structures + else if (obj.val == "data") { + out.storageVars = getStorageVars(out.storageVars, + obj.args[0], + "", + storageDataCount); + storageDataCount += 1; + } + else any.push_back(obj); + } + // Set up top-level AST structure + std::vector main; + if (shared.args.size()) main.push_back(shared); + if (init.args.size()) main.push_back(init); + + std::vector code; + if (shared.args.size()) code.push_back(shared); + for (unsigned i = 0; i < any.size(); i++) + code.push_back(any[i]); + for (unsigned i = 0; i < functions.size(); i++) + code.push_back(functions[i]); + Node codeNode; + if (functions.size() > 0) { + codeNode = astnode("with", + token("__funid", m), + astnode("byte", + token("0", m), + astnode("calldataload", token("0", m), m), + m), + astnode("seq", code, m), + m); + } + else codeNode = astnode("seq", code, m); + main.push_back(astnode("~return", + token("0", m), + astnode("lll", + codeNode, + token("0", m), + m), + m)); + + + Node result; + if (main.size() == 1) result = main[0]; + else result = astnode("seq", main, inp.metadata); + return preprocessResult(result, out); +} + +preprocessResult processTypes (preprocessResult pr) { + preprocessAux aux = pr.second; + Node node = pr.first; + if (node.type == TOKEN && aux.types.count(node.val)) + node = asn(aux.types[node.val], node, node.metadata); + else if (node.val == "untyped") + return preprocessResult(node.args[0], aux); + else if (node.val == "outer") + return preprocessResult(node, aux); + else { + for (unsigned i = 0; i < node.args.size(); i++) { + node.args[i] = + processTypes(preprocessResult(node.args[i], aux)).first; + } + } + return preprocessResult(node, aux); +} + +preprocessResult preprocess(Node n) { + return processTypes(preprocessInit(n)); +} diff --git a/libserpent/preprocess.h b/libserpent/preprocess.h new file mode 100644 index 000000000..321fb8527 --- /dev/null +++ b/libserpent/preprocess.h @@ -0,0 +1,50 @@ +#ifndef ETHSERP_PREPROCESSOR +#define ETHSERP_PREPROCESSOR + +#include +#include +#include +#include +#include "util.h" +#include "rewriteutils.h" + +// Storage variable index storing object +struct svObj { + std::map offsets; + std::map indices; + std::map > coefficients; + std::map nonfinal; + std::string globalOffset; +}; + + + +// Preprocessing result storing object +class preprocessAux { + public: + preprocessAux() { + globalExterns = std::map(); + localExterns = std::map >(); + localExterns["self"] = std::map(); + } + std::map globalExterns; + std::map globalExternSigs; + std::map > localExterns; + std::map > localExternSigs; + std::map customMacros; + std::map types; + svObj storageVars; +}; + +#define preprocessResult std::pair + +// Populate an svObj with the arguments needed to determine +// the storage position of a node +svObj getStorageVars(svObj pre, Node node, std::string prefix="", + int index=0); + +// Preprocess a function (see cpp for details) +preprocessResult preprocess(Node inp); + + +#endif diff --git a/libserpent/rewriteutils.cpp b/libserpent/rewriteutils.cpp new file mode 100644 index 000000000..0d810bdbc --- /dev/null +++ b/libserpent/rewriteutils.cpp @@ -0,0 +1,211 @@ +#include +#include +#include +#include +#include "util.h" +#include "lllparser.h" +#include "bignum.h" +#include "rewriteutils.h" +#include "optimize.h" + +// Valid functions and their min and max argument counts +std::string validFunctions[][3] = { + { "if", "2", "3" }, + { "unless", "2", "2" }, + { "while", "2", "2" }, + { "until", "2", "2" }, + { "alloc", "1", "1" }, + { "array", "1", "1" }, + { "call", "2", tt256 }, + { "callcode", "2", tt256 }, + { "create", "1", "4" }, + { "getch", "2", "2" }, + { "setch", "3", "3" }, + { "sha3", "1", "2" }, + { "return", "1", "2" }, + { "inset", "1", "1" }, + { "min", "2", "2" }, + { "max", "2", "2" }, + { "array_lit", "0", tt256 }, + { "seq", "0", tt256 }, + { "log", "1", "6" }, + { "outer", "1", "1" }, + { "set", "2", "2" }, + { "get", "1", "1" }, + { "ref", "1", "1" }, + { "declare", "1", tt256 }, + { "with", "3", "3" }, + { "outer", "1", "1" }, + { "mcopy", "3", "3" }, + { "unsafe_mcopy", "3", "3" }, + { "save", "3", "3" }, + { "load", "2", "2" }, + { "---END---", "", "" } //Keep this line at the end of the list +}; + +std::map vfMap; + +// Is a function name one of the valid functions above? +bool isValidFunctionName(std::string f) { + if (vfMap.size() == 0) { + for (int i = 0; ; i++) { + if (validFunctions[i][0] == "---END---") break; + vfMap[validFunctions[i][0]] = true; + } + } + return vfMap.count(f); +} + +// Cool function for debug purposes (named cerrStringList to make +// all prints searchable via 'cerr') +void cerrStringList(std::vector s, std::string suffix) { + for (unsigned i = 0; i < s.size(); i++) std::cerr << s[i] << " "; + std::cerr << suffix << "\n"; +} + +// Convert: +// self.cow -> ["cow"] +// self.horse[0] -> ["horse", "0"] +// self.a[6][7][self.storage[3]].chicken[9] -> +// ["6", "7", (sload 3), "chicken", "9"] +std::vector listfyStorageAccess(Node node) { + std::vector out; + std::vector nodez; + nodez.push_back(node); + while (1) { + if (nodez.back().type == TOKEN) { + out.push_back(token("--" + nodez.back().val, node.metadata)); + std::vector outrev; + for (int i = (signed)out.size() - 1; i >= 0; i--) { + outrev.push_back(out[i]); + } + return outrev; + } + if (nodez.back().val == ".") + nodez.back().args[1].val = "--" + nodez.back().args[1].val; + if (nodez.back().args.size() == 0) + err("Error parsing storage variable statement", node.metadata); + if (nodez.back().args.size() == 1) + out.push_back(token(tt256m1, node.metadata)); + else + out.push_back(nodez.back().args[1]); + nodez.push_back(nodez.back().args[0]); + } +} + +// Is the given node something of the form +// self.cow +// self.horse[0] +// self.a[6][7][self.storage[3]].chicken[9] +bool isNodeStorageVariable(Node node) { + std::vector nodez; + nodez.push_back(node); + while (1) { + if (nodez.back().type == TOKEN) return false; + if (nodez.back().args.size() == 0) return false; + if (nodez.back().val != "." && nodez.back().val != "access") + return false; + if (nodez.back().args[0].val == "self") return true; + nodez.push_back(nodez.back().args[0]); + } +} + +// Main pattern matching routine, for those patterns that can be expressed +// using our standard mini-language above +// +// Returns two values. First, a boolean to determine whether the node matches +// the pattern, second, if the node does match then a map mapping variables +// in the pattern to nodes +matchResult match(Node p, Node n) { + matchResult o; + o.success = false; + if (p.type == TOKEN) { + if (p.val == n.val && n.type == TOKEN) o.success = true; + else if (p.val[0] == '$' || p.val[0] == '@') { + o.success = true; + o.map[p.val.substr(1)] = n; + } + } + else if (n.type==TOKEN || p.val!=n.val || p.args.size()!=n.args.size()) { + // do nothing + } + else { + for (unsigned i = 0; i < p.args.size(); i++) { + matchResult oPrime = match(p.args[i], n.args[i]); + if (!oPrime.success) { + o.success = false; + return o; + } + for (std::map::iterator it = oPrime.map.begin(); + it != oPrime.map.end(); + it++) { + o.map[(*it).first] = (*it).second; + } + } + o.success = true; + } + return o; +} + + +// Fills in the pattern with a dictionary mapping variable names to +// nodes (these dicts are generated by match). Match and subst together +// create a full pattern-matching engine. +Node subst(Node pattern, + std::map dict, + std::string varflag, + Metadata m) { + // Swap out patterns at the token level + if (pattern.metadata.ln == -1) + pattern.metadata = m; + if (pattern.type == TOKEN && + pattern.val[0] == '$') { + if (dict.count(pattern.val.substr(1))) { + return dict[pattern.val.substr(1)]; + } + else { + return token(varflag + pattern.val.substr(1), m); + } + } + // Other tokens are untouched + else if (pattern.type == TOKEN) { + return pattern; + } + // Substitute recursively for ASTs + else { + std::vector args; + for (unsigned i = 0; i < pattern.args.size(); i++) { + args.push_back(subst(pattern.args[i], dict, varflag, m)); + } + return asn(pattern.val, args, m); + } +} + +// Transforms a sequence containing two-argument with statements +// into a statement containing those statements in nested form +Node withTransform (Node source) { + Node o = token("--"); + Metadata m = source.metadata; + std::vector args; + for (int i = source.args.size() - 1; i >= 0; i--) { + Node a = source.args[i]; + if (a.val == "with" && a.args.size() == 2) { + std::vector flipargs; + for (int j = args.size() - 1; j >= 0; j--) + flipargs.push_back(args[i]); + if (o.val != "--") + flipargs.push_back(o); + o = asn("with", a.args[0], a.args[1], asn("seq", flipargs, m), m); + args = std::vector(); + } + else { + args.push_back(a); + } + } + std::vector flipargs; + for (int j = args.size() - 1; j >= 0; j--) + flipargs.push_back(args[j]); + if (o.val != "--") + flipargs.push_back(o); + return asn("seq", flipargs, m); +} diff --git a/libserpent/rewriteutils.h b/libserpent/rewriteutils.h new file mode 100644 index 000000000..3a9a837ad --- /dev/null +++ b/libserpent/rewriteutils.h @@ -0,0 +1,76 @@ +#ifndef ETHSERP_REWRITEUTILS +#define ETHSERP_REWRITEUTILS + +#include +#include +#include +#include +#include "util.h" + +// Valid functions and their min and max argument counts +extern std::string validFunctions[][3]; + +extern std::map vfMap; + +bool isValidFunctionName(std::string f); + +// Converts deep array access into ordered list of the arguments +// along the descent +std::vector listfyStorageAccess(Node node); + +// Cool function for debug purposes (named cerrStringList to make +// all prints searchable via 'cerr') +void cerrStringList(std::vector s, std::string suffix=""); + +// Is the given node something of the form +// self.cow +// self.horse[0] +// self.a[6][7][self.storage[3]].chicken[9] +bool isNodeStorageVariable(Node node); + +// Applies rewrite rules adding without wrapper +Node rewriteChunk(Node inp); + +// Match result storing object +struct matchResult { + bool success; + std::map map; +}; + +// Match node to pattern +matchResult match(Node p, Node n); + +// Substitute node using pattern +Node subst(Node pattern, + std::map dict, + std::string varflag, + Metadata m); + +Node withTransform(Node source); + +class rewriteRule { + public: + rewriteRule(Node p, Node s) { + pattern = p; + substitution = s; + } + Node pattern; + Node substitution; +}; + +class rewriteRuleSet { + public: + rewriteRuleSet() { + ruleLists = std::map >(); + } + void addRule(rewriteRule r) { + if (!ruleLists.count(r.pattern.val)) + ruleLists[r.pattern.val] = std::vector(); + ruleLists[r.pattern.val].push_back(r); + } + std::map > ruleLists; +}; + + + +#endif From 0b5b6c7cd40adc20944067bca42a9434c70a51d1 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Thu, 18 Dec 2014 16:27:17 +0100 Subject: [PATCH 264/277] Adressing some natspec issues --- libsolidity/InterfaceHandler.cpp | 4 ++-- libsolidity/Scanner.cpp | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/libsolidity/InterfaceHandler.cpp b/libsolidity/InterfaceHandler.cpp index 9ae284b40..5b5682ff1 100644 --- a/libsolidity/InterfaceHandler.cpp +++ b/libsolidity/InterfaceHandler.cpp @@ -170,7 +170,7 @@ std::string::const_iterator InterfaceHandler::parseDocTagLine(std::string::const bool _appending) { auto nlPos = std::find(_pos, _end, '\n'); - if (_appending && *_pos != ' ') + if (_appending && _pos < _end && *_pos != ' ') _tagString += " "; std::copy(_pos, nlPos, back_inserter(_tagString)); m_lastTag = _tagType; @@ -204,7 +204,7 @@ std::string::const_iterator InterfaceHandler::appendDocTagParam(std::string::con solAssert(!m_params.empty(), "Internal: Tried to append to empty parameter"); auto pair = m_params.back(); - if (*_pos != ' ') + if (_pos < _end && *_pos != ' ') pair.second += " "; auto nlPos = std::find(_pos, _end, '\n'); std::copy(_pos, nlPos, back_inserter(pair.second)); diff --git a/libsolidity/Scanner.cpp b/libsolidity/Scanner.cpp index 69b61ce4b..90a3b4545 100644 --- a/libsolidity/Scanner.cpp +++ b/libsolidity/Scanner.cpp @@ -328,6 +328,7 @@ Token::Value Scanner::scanMultiLineDocComment() void Scanner::scanToken() { + int savedPosition; m_nextToken.literal.clear(); m_nextSkippedComment.literal.clear(); Token::Value token; @@ -428,6 +429,7 @@ void Scanner::scanToken() break; case '/': // / // /* /= + savedPosition = getSourcePos(); advance(); if (m_char == '/') { @@ -436,7 +438,7 @@ void Scanner::scanToken() else if (m_char == '/') { Token::Value comment; - m_nextSkippedComment.location.start = getSourcePos(); + m_nextSkippedComment.location.start = savedPosition; comment = scanSingleLineDocComment(); m_nextSkippedComment.location.end = getSourcePos(); m_nextSkippedComment.token = comment; @@ -447,12 +449,13 @@ void Scanner::scanToken() } else if (m_char == '*') { + // /** doxygent style natspec comment if (!advance()) /* slash star comment before EOS */ token = Token::WHITESPACE; else if (m_char == '*') { Token::Value comment; - m_nextSkippedComment.location.start = getSourcePos(); + m_nextSkippedComment.location.start = savedPosition; comment = scanMultiLineDocComment(); m_nextSkippedComment.location.end = getSourcePos(); m_nextSkippedComment.token = comment; From 73593674419a4c2e2aea7a03a554b5577aa31405 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Thu, 18 Dec 2014 16:48:25 +0100 Subject: [PATCH 265/277] More multiline natspec tests and small issue fix --- libsolidity/Scanner.cpp | 4 ++-- test/solidityScanner.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/libsolidity/Scanner.cpp b/libsolidity/Scanner.cpp index 90a3b4545..124c88d92 100644 --- a/libsolidity/Scanner.cpp +++ b/libsolidity/Scanner.cpp @@ -212,7 +212,7 @@ bool Scanner::skipWhitespace() bool Scanner::skipWhitespaceExceptLF() { int const startPosition = getSourcePos(); - while (m_char == ' ' || m_char == '\t') + while (isWhiteSpace(m_char) && !isLineTerminator(m_char)) advance(); // Return whether or not we skipped any characters. return getSourcePos() != startPosition; @@ -305,7 +305,7 @@ Token::Value Scanner::scanMultiLineDocComment() endFound = true; break; } - else + else if (charsAdded) addCommentLiteralChar('\n'); } diff --git a/test/solidityScanner.cpp b/test/solidityScanner.cpp index 159e53055..355ea9e22 100644 --- a/test/solidityScanner.cpp +++ b/test/solidityScanner.cpp @@ -189,6 +189,30 @@ BOOST_AUTO_TEST_CASE(multiline_documentation_comments_parsed) BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), "Send $(value / 1000) chocolates to the user"); } +BOOST_AUTO_TEST_CASE(multiline_documentation_no_stars) +{ + Scanner scanner(CharStream("some other tokens /**\n" + " Send $(value / 1000) chocolates to the user\n" + "*/")); + BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::IDENTIFIER); + BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER); + BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER); + BOOST_CHECK_EQUAL(scanner.next(), Token::EOS); + BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), "Send $(value / 1000) chocolates to the user"); +} + +BOOST_AUTO_TEST_CASE(multiline_documentation_whitespace_hell) +{ + Scanner scanner(CharStream("some other tokens /** \t \r \n" + "\t \r * Send $(value / 1000) chocolates to the user\n" + "*/")); + BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::IDENTIFIER); + BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER); + BOOST_CHECK_EQUAL(scanner.next(), Token::IDENTIFIER); + BOOST_CHECK_EQUAL(scanner.next(), Token::EOS); + BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), "Send $(value / 1000) chocolates to the user"); +} + BOOST_AUTO_TEST_CASE(comment_before_eos) { Scanner scanner(CharStream("//")); From b162e267acee2654e000a71af05b5d93db0d613f Mon Sep 17 00:00:00 2001 From: ethdev Date: Thu, 18 Dec 2014 17:10:00 +0100 Subject: [PATCH 266/277] windows fixes --- libserpent/compiler.cpp | 2 +- libserpent/rewriteutils.cpp | 1 + libserpent/util.cpp | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libserpent/compiler.cpp b/libserpent/compiler.cpp index a3e5b1c60..886eee6df 100644 --- a/libserpent/compiler.cpp +++ b/libserpent/compiler.cpp @@ -173,7 +173,7 @@ programData opcodeify(Node node, } // Comments do nothing else if (node.val == "comment") { - Node nodelist[] = { }; + Node* nodelist = nullptr; return pd(aux, multiToken(nodelist, 0, m), 0); } // Custom operation sequence diff --git a/libserpent/rewriteutils.cpp b/libserpent/rewriteutils.cpp index 0d810bdbc..e6429434a 100644 --- a/libserpent/rewriteutils.cpp +++ b/libserpent/rewriteutils.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "util.h" #include "lllparser.h" #include "bignum.h" diff --git a/libserpent/util.cpp b/libserpent/util.cpp index 5e83c0e41..4b99a5ea5 100644 --- a/libserpent/util.cpp +++ b/libserpent/util.cpp @@ -5,6 +5,7 @@ #include "util.h" #include "bignum.h" #include +#include #include //Token or value node constructor From d14ed2d4dc29afcce8c16a0173d7a4e87b2c5974 Mon Sep 17 00:00:00 2001 From: Christian Date: Thu, 18 Dec 2014 17:04:20 +0100 Subject: [PATCH 267/277] Bit operators should bind more strongly than comparison operators. --- libsolidity/Token.h | 20 ++++++++++---------- test/SolidityNameAndTypeResolution.cpp | 10 ++++++++++ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/libsolidity/Token.h b/libsolidity/Token.h index 32656096a..897d6eaaa 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -107,9 +107,9 @@ namespace solidity T(COMMA, ",", 1) \ T(OR, "||", 4) \ T(AND, "&&", 5) \ - T(BIT_OR, "|", 6) \ - T(BIT_XOR, "^", 7) \ - T(BIT_AND, "&", 8) \ + T(BIT_OR, "|", 8) \ + T(BIT_XOR, "^", 9) \ + T(BIT_AND, "&", 10) \ T(SHL, "<<", 11) \ T(SAR, ">>", 11) \ T(SHR, ">>>", 11) \ @@ -122,13 +122,13 @@ namespace solidity /* Compare operators sorted by precedence. */ \ /* IsCompareOp() relies on this block of enum values */ \ /* being contiguous and sorted in the same order! */ \ - T(EQ, "==", 9) \ - T(NE, "!=", 9) \ - T(LT, "<", 10) \ - T(GT, ">", 10) \ - T(LTE, "<=", 10) \ - T(GTE, ">=", 10) \ - K(IN, "in", 10) \ + T(EQ, "==", 6) \ + T(NE, "!=", 6) \ + T(LT, "<", 7) \ + T(GT, ">", 7) \ + T(LTE, "<=", 7) \ + T(GTE, ">=", 7) \ + K(IN, "in", 7) \ \ /* Unary operators. */ \ /* IsUnaryOp() relies on this block of enum values */ \ diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index 0bda0a1fd..c7f0b3ab8 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -311,6 +311,16 @@ BOOST_AUTO_TEST_CASE(forward_function_reference) BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); } +BOOST_AUTO_TEST_CASE(comparison_bitop_precedence) +{ + char const* text = "contract First {\n" + " function fun() returns (bool ret) {\n" + " return 1 & 2 == 8 & 9;\n" + " }\n" + "}\n"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + BOOST_AUTO_TEST_SUITE_END() } From 49f60a1d6d0b93fad28cea57e03beb261d9f09b1 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Thu, 18 Dec 2014 17:30:10 +0100 Subject: [PATCH 268/277] Factoring forward slash scanning out to its own function --- libsolidity/Scanner.cpp | 85 ++++++++++++++++++++++------------------- libsolidity/Scanner.h | 2 + 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/libsolidity/Scanner.cpp b/libsolidity/Scanner.cpp index 124c88d92..f22e69bc8 100644 --- a/libsolidity/Scanner.cpp +++ b/libsolidity/Scanner.cpp @@ -326,9 +326,52 @@ Token::Value Scanner::scanMultiLineDocComment() return Token::COMMENT_LITERAL; } +Token::Value Scanner::scanSlash() +{ + int firstSlashPosition = getSourcePos(); + advance(); + if (m_char == '/') + { + if (!advance()) /* double slash comment directly before EOS */ + return Token::WHITESPACE; + else if (m_char == '/') + { + // doxygen style /// comment + Token::Value comment; + m_nextSkippedComment.location.start = firstSlashPosition; + comment = scanSingleLineDocComment(); + m_nextSkippedComment.location.end = getSourcePos(); + m_nextSkippedComment.token = comment; + return Token::WHITESPACE; + } + else + return skipSingleLineComment(); + } + else if (m_char == '*') + { + // doxygen style /** natspec comment + if (!advance()) /* slash star comment before EOS */ + return Token::WHITESPACE; + else if (m_char == '*') + { + Token::Value comment; + m_nextSkippedComment.location.start = firstSlashPosition; + comment = scanMultiLineDocComment(); + m_nextSkippedComment.location.end = getSourcePos(); + m_nextSkippedComment.token = comment; + return Token::WHITESPACE; + } + else + return skipMultiLineComment(); + } + else if (m_char == '=') + return selectToken(Token::ASSIGN_DIV); + else + return Token::DIV; +} + void Scanner::scanToken() { - int savedPosition; m_nextToken.literal.clear(); m_nextSkippedComment.literal.clear(); Token::Value token; @@ -429,45 +472,7 @@ void Scanner::scanToken() break; case '/': // / // /* /= - savedPosition = getSourcePos(); - advance(); - if (m_char == '/') - { - if (!advance()) /* double slash comment directly before EOS */ - token = Token::WHITESPACE; - else if (m_char == '/') - { - Token::Value comment; - m_nextSkippedComment.location.start = savedPosition; - comment = scanSingleLineDocComment(); - m_nextSkippedComment.location.end = getSourcePos(); - m_nextSkippedComment.token = comment; - token = Token::WHITESPACE; - } - else - token = skipSingleLineComment(); - } - else if (m_char == '*') - { - // /** doxygent style natspec comment - if (!advance()) /* slash star comment before EOS */ - token = Token::WHITESPACE; - else if (m_char == '*') - { - Token::Value comment; - m_nextSkippedComment.location.start = savedPosition; - comment = scanMultiLineDocComment(); - m_nextSkippedComment.location.end = getSourcePos(); - m_nextSkippedComment.token = comment; - token = Token::WHITESPACE; - } - else - token = skipMultiLineComment(); - } - else if (m_char == '=') - token = selectToken(Token::ASSIGN_DIV); - else - token = Token::DIV; + token = scanSlash(); break; case '&': // & && &= diff --git a/libsolidity/Scanner.h b/libsolidity/Scanner.h index 5e70db51d..5b90a94eb 100644 --- a/libsolidity/Scanner.h +++ b/libsolidity/Scanner.h @@ -194,6 +194,8 @@ private: Token::Value scanString(); Token::Value scanSingleLineDocComment(); Token::Value scanMultiLineDocComment(); + /// Scans a slash '/' and depending on the characters returns the appropriate token + Token::Value scanSlash(); /// Scans an escape-sequence which is part of a string and adds the /// decoded character to the current literal. Returns true if a pattern From ae994f28043065ef9ff8c3a2835a69389a495029 Mon Sep 17 00:00:00 2001 From: Christian Date: Thu, 18 Dec 2014 17:49:11 +0100 Subject: [PATCH 269/277] Also test non-equality comparison operator. --- test/SolidityNameAndTypeResolution.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index c7f0b3ab8..25bff71f7 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -315,7 +315,7 @@ BOOST_AUTO_TEST_CASE(comparison_bitop_precedence) { char const* text = "contract First {\n" " function fun() returns (bool ret) {\n" - " return 1 & 2 == 8 & 9;\n" + " return 1 & 2 == 8 & 9 && 1 ^ 2 < 4 | 6;\n" " }\n" "}\n"; BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); From 4165e45464eaec9ed8f62d2571f2a10111599376 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Thu, 18 Dec 2014 18:16:43 +0100 Subject: [PATCH 270/277] updating solidity parser natspec tests to comply with recent changes --- test/SolidityParser.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/SolidityParser.cpp b/test/SolidityParser.cpp index f978cdd9b..c14c05122 100644 --- a/test/SolidityParser.cpp +++ b/test/SolidityParser.cpp @@ -128,7 +128,7 @@ BOOST_AUTO_TEST_CASE(function_natspec_documentation) BOOST_REQUIRE_NO_THROW(contract = parseText(text)); auto functions = contract->getDefinedFunctions(); BOOST_REQUIRE_NO_THROW(function = functions.at(0)); - BOOST_CHECK_EQUAL(*function->getDocumentation(), " This is a test function"); + BOOST_CHECK_EQUAL(*function->getDocumentation(), "This is a test function"); } BOOST_AUTO_TEST_CASE(function_normal_comments) @@ -166,17 +166,17 @@ BOOST_AUTO_TEST_CASE(multiple_functions_natspec_documentation) auto functions = contract->getDefinedFunctions(); BOOST_REQUIRE_NO_THROW(function = functions.at(0)); - BOOST_CHECK_EQUAL(*function->getDocumentation(), " This is test function 1"); + BOOST_CHECK_EQUAL(*function->getDocumentation(), "This is test function 1"); BOOST_REQUIRE_NO_THROW(function = functions.at(1)); - BOOST_CHECK_EQUAL(*function->getDocumentation(), " This is test function 2"); + BOOST_CHECK_EQUAL(*function->getDocumentation(), "This is test function 2"); BOOST_REQUIRE_NO_THROW(function = functions.at(2)); BOOST_CHECK_MESSAGE(function->getDocumentation() == nullptr, "Should not have gotten natspec comment for functionName3()"); BOOST_REQUIRE_NO_THROW(function = functions.at(3)); - BOOST_CHECK_EQUAL(*function->getDocumentation(), " This is test function 4"); + BOOST_CHECK_EQUAL(*function->getDocumentation(), "This is test function 4"); } BOOST_AUTO_TEST_CASE(multiline_function_documentation) @@ -194,7 +194,7 @@ BOOST_AUTO_TEST_CASE(multiline_function_documentation) BOOST_REQUIRE_NO_THROW(function = functions.at(0)); BOOST_CHECK_EQUAL(*function->getDocumentation(), - " This is a test function\n" + "This is a test function\n" " and it has 2 lines"); } @@ -220,11 +220,11 @@ BOOST_AUTO_TEST_CASE(natspec_comment_in_function_body) auto functions = contract->getDefinedFunctions(); BOOST_REQUIRE_NO_THROW(function = functions.at(0)); - BOOST_CHECK_EQUAL(*function->getDocumentation(), " fun1 description"); + BOOST_CHECK_EQUAL(*function->getDocumentation(), "fun1 description"); BOOST_REQUIRE_NO_THROW(function = functions.at(1)); BOOST_CHECK_EQUAL(*function->getDocumentation(), - " This is a test function\n" + "This is a test function\n" " and it has 2 lines"); } From 672c1ca15b5d749609ef8c68267fe58e9a69e6e8 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 18 Dec 2014 18:44:55 +0100 Subject: [PATCH 271/277] Version bump. --- libdevcore/Common.cpp | 2 +- libethcore/CommonEth.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libdevcore/Common.cpp b/libdevcore/Common.cpp index 55250b418..1de7ef957 100644 --- a/libdevcore/Common.cpp +++ b/libdevcore/Common.cpp @@ -27,7 +27,7 @@ using namespace dev; namespace dev { -char const* Version = "0.7.12"; +char const* Version = "0.7.13"; } diff --git a/libethcore/CommonEth.cpp b/libethcore/CommonEth.cpp index 5e510572e..ff5e6aed0 100644 --- a/libethcore/CommonEth.cpp +++ b/libethcore/CommonEth.cpp @@ -32,7 +32,7 @@ namespace dev namespace eth { -const unsigned c_protocolVersion = 49; +const unsigned c_protocolVersion = 50; const unsigned c_databaseVersion = 5; static const vector> g_units = From fce7f1712d32bb3f3c0c56078201adda4541be2b Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 18 Dec 2014 21:43:40 +0100 Subject: [PATCH 272/277] more refunds tests --- test/stRefundTestFiller.json | 163 +++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) diff --git a/test/stRefundTestFiller.json b/test/stRefundTestFiller.json index 4060bbb72..6b2b2fc15 100644 --- a/test/stRefundTestFiller.json +++ b/test/stRefundTestFiller.json @@ -141,5 +141,168 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } + }, + + "refund50_1" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 1 ]] 0 [[ 2 ]] 0 [[ 3 ]] 0 [[ 4 ]] 0 [[ 5 ]] 0 }", + "storage" : { + "0x01" : "0x01", + "0x02" : "0x01", + "0x03" : "0x01", + "0x04" : "0x01", + "0x05" : "0x01" + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "10000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "refund50_2" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 10 ]] 1 [[ 11 ]] 1 [[ 1 ]] 0 [[ 2 ]] 0 [[ 3 ]] 0 [[ 4 ]] 0 [[ 5 ]] 0 }", + "storage" : { + "0x01" : "0x01", + "0x02" : "0x01", + "0x03" : "0x01", + "0x04" : "0x01", + "0x05" : "0x01" + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "10000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "refund500" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ @@1 @@2 [[ 10 ]] (EXP 2 0xff) [[ 11 ]] (BALANCE (ADDRESS)) [[ 1 ]] 0 [[ 2 ]] 0 [[ 3 ]] 0 [[ 4 ]] 0 [[ 5 ]] 0 [[ 6 ]] 0 }", + "storage" : { + "0x01" : "0x01", + "0x02" : "0x01", + "0x03" : "0x01", + "0x04" : "0x01", + "0x05" : "0x01", + "0x06" : "0x01" + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "10000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "refund600" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ @@1 @@2 [[ 10 ]] (EXP 2 0xffff) [[ 11 ]] (BALANCE (ADDRESS)) [[ 1 ]] 0 [[ 2 ]] 0 [[ 3 ]] 0 [[ 4 ]] 0 [[ 5 ]] 0 [[ 6 ]] 0 }", + "storage" : { + "0x01" : "0x01", + "0x02" : "0x01", + "0x03" : "0x01", + "0x04" : "0x01", + "0x05" : "0x01", + "0x06" : "0x01" + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000", + "nonce" : 0, + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "10000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } } + } From e427a0a2cafa5ecd4ea3872aadd2b5f19eb705cb Mon Sep 17 00:00:00 2001 From: Christian Date: Thu, 18 Dec 2014 22:15:11 +0100 Subject: [PATCH 273/277] Bugfix: Additional swap for compound assignment. --- libsolidity/ExpressionCompiler.cpp | 2 ++ test/SolidityEndToEndTest.cpp | 35 ++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index f58c157d9..cf641935a 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -62,6 +62,8 @@ bool ExpressionCompiler::visit(Assignment const& _assignment) m_context << eth::Instruction::SWAP1 << eth::Instruction::DUP2; m_currentLValue.retrieveValue(_assignment, true); appendOrdinaryBinaryOperatorCode(Token::AssignmentToBinaryOp(op), *_assignment.getType()); + if (m_currentLValue.storesReferenceOnStack()) + m_context << eth::Instruction::SWAP1; } m_currentLValue.storeValue(_assignment); m_currentLValue.reset(); diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index aa74f8186..9559e3702 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -504,6 +504,41 @@ BOOST_AUTO_TEST_CASE(state_smoke_test) BOOST_CHECK(callContractFunction(0, bytes(1, 0x00)) == toBigEndian(u256(0x3))); } +BOOST_AUTO_TEST_CASE(compound_assign) +{ + char const* sourceCode = "contract test {\n" + " uint value1;\n" + " uint value2;\n" + " function f(uint x, uint y) returns (uint w) {\n" + " uint value3 = y;" + " value1 += x;\n" + " value3 *= x;" + " value2 *= value3 + value1;\n" + " return value2 += 7;" + " }\n" + "}\n"; + compileAndRun(sourceCode); + + u256 value1; + u256 value2; + auto f = [&](u256 const& _x, u256 const& _y) -> u256 + { + u256 value3 = _y; + value1 += _x; + value3 *= _x; + value2 *= value3 + value1; + return value2 += 7; + }; + testSolidityAgainstCpp(0, f, u256(0), u256(6)); + testSolidityAgainstCpp(0, f, u256(1), u256(3)); + testSolidityAgainstCpp(0, f, u256(2), u256(25)); + testSolidityAgainstCpp(0, f, u256(3), u256(69)); + testSolidityAgainstCpp(0, f, u256(4), u256(84)); + testSolidityAgainstCpp(0, f, u256(5), u256(2)); + testSolidityAgainstCpp(0, f, u256(6), u256(51)); + testSolidityAgainstCpp(0, f, u256(7), u256(48)); +} + BOOST_AUTO_TEST_CASE(simple_mapping) { char const* sourceCode = "contract test {\n" From f3f5d9ea745bef9455de82fcd57ab9d1dc0b350d Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 18 Dec 2014 23:02:41 +0100 Subject: [PATCH 274/277] correct VMTrace define --- libethereum/State.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libethereum/State.cpp b/libethereum/State.cpp index fd00761e1..e02b06bcd 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -1017,7 +1017,7 @@ u256 State::execute(bytesConstRef _rlp, bytes* o_output, bool _commit) ctrace << "Executing" << e.t() << "on" << h; ctrace << toHex(e.t().rlp()); #endif -#if ETH_TRACE +#if ETH_VMTRACE e.go(e.simpleTrace()); #else e.go(); From 29261206b9293c2e07b2b879aff059bc57e5d1cb Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 19 Dec 2014 10:48:59 +0100 Subject: [PATCH 275/277] Adding const attribute to ABI output --- libsolidity/InterfaceHandler.cpp | 1 + test/SolidityABIJSON.cpp | 53 ++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/libsolidity/InterfaceHandler.cpp b/libsolidity/InterfaceHandler.cpp index 5b5682ff1..60971fbb9 100644 --- a/libsolidity/InterfaceHandler.cpp +++ b/libsolidity/InterfaceHandler.cpp @@ -56,6 +56,7 @@ std::unique_ptr InterfaceHandler::getABIInterface(ContractDefinitio }; method["name"] = f->getName(); + method["const"] = f->isDeclaredConst(); method["inputs"] = populateParameters(f->getParameters()); method["outputs"] = populateParameters(f->getReturnParameters()); methods.append(method); diff --git a/test/SolidityABIJSON.cpp b/test/SolidityABIJSON.cpp index c734009c3..62ab0458c 100644 --- a/test/SolidityABIJSON.cpp +++ b/test/SolidityABIJSON.cpp @@ -76,6 +76,7 @@ BOOST_AUTO_TEST_CASE(basic_test) char const* interface = R"([ { "name": "f", + "const": false, "inputs": [ { "name": "a", @@ -114,6 +115,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods) char const* interface = R"([ { "name": "f", + "const": false, "inputs": [ { "name": "a", @@ -129,6 +131,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods) }, { "name": "g", + "const": false, "inputs": [ { "name": "b", @@ -156,6 +159,7 @@ BOOST_AUTO_TEST_CASE(multiple_params) char const* interface = R"([ { "name": "f", + "const": false, "inputs": [ { "name": "a", @@ -189,6 +193,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods_order) char const* interface = R"([ { "name": "c", + "const": false, "inputs": [ { "name": "b", @@ -204,6 +209,7 @@ BOOST_AUTO_TEST_CASE(multiple_methods_order) }, { "name": "f", + "const": false, "inputs": [ { "name": "a", @@ -222,6 +228,53 @@ BOOST_AUTO_TEST_CASE(multiple_methods_order) checkInterface(sourceCode, interface); } +BOOST_AUTO_TEST_CASE(const_function) +{ + char const* sourceCode = "contract test {\n" + " function foo(uint a, uint b) returns(uint d) { return a + b; }\n" + " function boo(uint32 a) const returns(uint b) { return a * 4; }\n" + "}\n"; + + char const* interface = R"([ + { + "name": "boo", + "const": true, + "inputs": [{ + "name": "a", + "type": "uint32" + }], + "outputs": [ + { + "name": "b", + "type": "uint256" + } + ] + }, + { + "name": "foo", + "const": false, + "inputs": [ + { + "name": "a", + "type": "uint256" + }, + { + "name": "b", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "d", + "type": "uint256" + } + ] + } + ])"; + + checkInterface(sourceCode, interface); +} + BOOST_AUTO_TEST_SUITE_END() } From e80dffeec5fb54e80e4c0ee3c90be4843db0c101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Fri, 19 Dec 2014 12:32:36 +0100 Subject: [PATCH 276/277] Clean up and remove some explicit dependencies in cmake files --- alethzero/CMakeLists.txt | 3 --- evmjit | 2 +- libethereum/CMakeLists.txt | 3 --- libevm/CMakeLists.txt | 3 +++ test/CMakeLists.txt | 3 --- 5 files changed, 4 insertions(+), 10 deletions(-) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index 4e4e4a93c..39c02d6be 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -46,9 +46,6 @@ target_link_libraries(${EXECUTABLE} evmcore) target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} web3jsonrpc) target_link_libraries(${EXECUTABLE} jsqrc) -if (EVMJIT) - target_link_libraries(${EXECUTEABLE} evmjit) -endif() # eth_install_executable is defined in cmake/EthExecutableHelper.cmake eth_install_executable(${EXECUTABLE}) diff --git a/evmjit b/evmjit index 8287c6040..232f9fee5 160000 --- a/evmjit +++ b/evmjit @@ -1 +1 @@ -Subproject commit 8287c6040a4900cb8b091ffbe284c7f478c60c49 +Subproject commit 232f9fee527e454f4008c2c03a9c7dac1c5c85ff diff --git a/libethereum/CMakeLists.txt b/libethereum/CMakeLists.txt index e00637dad..3906074fd 100644 --- a/libethereum/CMakeLists.txt +++ b/libethereum/CMakeLists.txt @@ -34,9 +34,6 @@ target_link_libraries(${EXECUTABLE} p2p) target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} secp256k1) -if (EVMJIT) - target_link_libraries(${EXECUTABLE} evmjit-cpp) -endif() install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/libevm/CMakeLists.txt b/libevm/CMakeLists.txt index 96b8f9ade..4af5eb175 100644 --- a/libevm/CMakeLists.txt +++ b/libevm/CMakeLists.txt @@ -30,6 +30,9 @@ target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} evmcore) target_link_libraries(${EXECUTABLE} devcore) +if (EVMJIT) + target_link_libraries(${EXECUTABLE} evmjit-cpp) +endif() install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 441200fe4..7cedc117b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -25,9 +25,6 @@ if (JSONRPC) target_link_libraries(testeth web3jsonrpc) target_link_libraries(testeth ${JSON_RPC_CPP_CLIENT_LIBRARIES}) endif() -if (EVMJIT) - target_link_libraries(testeth evmjit-cpp) -endif() target_link_libraries(createRandomTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) target_link_libraries(createRandomTest ethereum) From 6be33f7d8f6dc99b4d32c6538d183ce1af89a8da Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 19 Dec 2014 13:45:12 +0100 Subject: [PATCH 277/277] Revert to 49. --- libethcore/CommonEth.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libethcore/CommonEth.cpp b/libethcore/CommonEth.cpp index ff5e6aed0..5e510572e 100644 --- a/libethcore/CommonEth.cpp +++ b/libethcore/CommonEth.cpp @@ -32,7 +32,7 @@ namespace dev namespace eth { -const unsigned c_protocolVersion = 50; +const unsigned c_protocolVersion = 49; const unsigned c_databaseVersion = 5; static const vector> g_units =