diff options
author | Jeff Garzik <jgarzik@bitpay.com> | 2014-06-23 23:16:33 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@bitpay.com> | 2014-07-29 11:13:27 -0400 |
commit | b2aeaa79393608132104183eba117fcbf583148e (patch) | |
tree | 98bc68b1a815c0afe644e56e6fa6eb47297fe355 | |
parent | ae775b5b311982a3d932a9e34ddc94ce597dcaaf (diff) |
Move ParseScript() helper, becoming accessible outside src/test/
-rw-r--r-- | src/core_io.h | 2 | ||||
-rw-r--r-- | src/core_read.cpp | 77 | ||||
-rw-r--r-- | src/test/script_tests.cpp | 71 | ||||
-rw-r--r-- | src/test/transaction_tests.cpp | 2 |
4 files changed, 81 insertions, 71 deletions
diff --git a/src/core_io.h b/src/core_io.h index 257dac3627..528c472803 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -3,9 +3,11 @@ #include <string> +class CScript; class CTransaction; // core_read.cpp +extern CScript ParseScript(std::string s); extern bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx); // core_write.cpp diff --git a/src/core_read.cpp b/src/core_read.cpp index 937dcd9c12..d5d3cca480 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -3,8 +3,85 @@ #include "core_io.h" #include "core.h" #include "serialize.h" +#include "script.h" + +#include <boost/assign/list_of.hpp> +#include <boost/algorithm/string/classification.hpp> +#include <boost/algorithm/string/predicate.hpp> +#include <boost/algorithm/string/split.hpp> +#include <boost/algorithm/string/replace.hpp> using namespace std; +using namespace boost; +using namespace boost::algorithm; + +CScript ParseScript(std::string s) +{ + CScript result; + + static map<string, opcodetype> mapOpNames; + + if (mapOpNames.size() == 0) + { + for (int op = 0; op <= OP_NOP10; op++) + { + // Allow OP_RESERVED to get into mapOpNames + if (op < OP_NOP && op != OP_RESERVED) + continue; + + const char* name = GetOpName((opcodetype)op); + if (strcmp(name, "OP_UNKNOWN") == 0) + continue; + string strName(name); + mapOpNames[strName] = (opcodetype)op; + // Convenience: OP_ADD and just ADD are both recognized: + replace_first(strName, "OP_", ""); + mapOpNames[strName] = (opcodetype)op; + } + } + + vector<string> words; + split(words, s, is_any_of(" \t\n"), token_compress_on); + + BOOST_FOREACH(string w, words) + { + if (w.size() == 0) + { + // Empty string, ignore. (boost::split given '' will return one word) + } + else if (all(w, is_digit()) || + (starts_with(w, "-") && all(string(w.begin()+1, w.end()), is_digit()))) + { + // Number + int64_t n = atoi64(w); + result << n; + } + else if (starts_with(w, "0x") && IsHex(string(w.begin()+2, w.end()))) + { + // Raw hex data, inserted NOT pushed onto stack: + std::vector<unsigned char> raw = ParseHex(string(w.begin()+2, w.end())); + result.insert(result.end(), raw.begin(), raw.end()); + } + else if (w.size() >= 2 && starts_with(w, "'") && ends_with(w, "'")) + { + // Single-quoted string, pushed as data. NOTE: this is poor-man's + // parsing, spaces/tabs/newlines in single-quoted strings won't work. + std::vector<unsigned char> value(w.begin()+1, w.end()-1); + result << value; + } + else if (mapOpNames.count(w)) + { + // opcode, e.g. OP_ADD or ADD: + result << mapOpNames[w]; + } + else + { + throw runtime_error("script parse error"); + } + } + + return result; +} bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx) { diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index cba582e941..5e35875a8e 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -10,6 +10,7 @@ #include "key.h" #include "keystore.h" #include "main.h" +#include "core_io.h" #include <fstream> #include <stdint.h> @@ -36,76 +37,6 @@ extern uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo static const unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC; -CScript -ParseScript(string s) -{ - CScript result; - - static map<string, opcodetype> mapOpNames; - - if (mapOpNames.size() == 0) - { - for (int op = 0; op <= OP_NOP10; op++) - { - // Allow OP_RESERVED to get into mapOpNames - if (op < OP_NOP && op != OP_RESERVED) - continue; - - const char* name = GetOpName((opcodetype)op); - if (strcmp(name, "OP_UNKNOWN") == 0) - continue; - string strName(name); - mapOpNames[strName] = (opcodetype)op; - // Convenience: OP_ADD and just ADD are both recognized: - replace_first(strName, "OP_", ""); - mapOpNames[strName] = (opcodetype)op; - } - } - - vector<string> words; - split(words, s, is_any_of(" \t\n"), token_compress_on); - - BOOST_FOREACH(string w, words) - { - if (w.size() == 0) - { - // Empty string, ignore. (boost::split given '' will return one word) - } - else if (all(w, is_digit()) || - (starts_with(w, "-") && all(string(w.begin()+1, w.end()), is_digit()))) - { - // Number - int64_t n = atoi64(w); - result << n; - } - else if (starts_with(w, "0x") && IsHex(string(w.begin()+2, w.end()))) - { - // Raw hex data, inserted NOT pushed onto stack: - std::vector<unsigned char> raw = ParseHex(string(w.begin()+2, w.end())); - result.insert(result.end(), raw.begin(), raw.end()); - } - else if (w.size() >= 2 && starts_with(w, "'") && ends_with(w, "'")) - { - // Single-quoted string, pushed as data. NOTE: this is poor-man's - // parsing, spaces/tabs/newlines in single-quoted strings won't work. - std::vector<unsigned char> value(w.begin()+1, w.end()-1); - result << value; - } - else if (mapOpNames.count(w)) - { - // opcode, e.g. OP_ADD or ADD: - result << mapOpNames[w]; - } - else - { - BOOST_ERROR("Parse error: " << s); - return CScript(); - } - } - - return result; -} - Array read_json(const std::string& jsondata) { diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 238033f407..03919e7c7d 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -9,6 +9,7 @@ #include "keystore.h" #include "main.h" #include "script.h" +#include "core_io.h" #include <map> #include <string> @@ -24,7 +25,6 @@ using namespace boost::algorithm; // In script_tests.cpp extern Array read_json(const std::string& jsondata); -extern CScript ParseScript(string s); unsigned int ParseFlags(string strFlags){ unsigned int flags = 0; |