aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core_io.h2
-rw-r--r--src/core_read.cpp77
-rw-r--r--src/test/script_tests.cpp71
-rw-r--r--src/test/transaction_tests.cpp2
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;