Skip to content

Commit b2aeaa7

Browse files
author
Jeff Garzik
committed
Move ParseScript() helper, becoming accessible outside src/test/
1 parent ae775b5 commit b2aeaa7

File tree

4 files changed

+81
-71
lines changed

4 files changed

+81
-71
lines changed

src/core_io.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33

44
#include <string>
55

6+
class CScript;
67
class CTransaction;
78

89
// core_read.cpp
10+
extern CScript ParseScript(std::string s);
911
extern bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx);
1012

1113
// core_write.cpp

src/core_read.cpp

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,85 @@
33
#include "core_io.h"
44
#include "core.h"
55
#include "serialize.h"
6+
#include "script.h"
7+
8+
#include <boost/assign/list_of.hpp>
9+
#include <boost/algorithm/string/classification.hpp>
10+
#include <boost/algorithm/string/predicate.hpp>
11+
#include <boost/algorithm/string/split.hpp>
12+
#include <boost/algorithm/string/replace.hpp>
613

714
using namespace std;
15+
using namespace boost;
16+
using namespace boost::algorithm;
17+
18+
CScript ParseScript(std::string s)
19+
{
20+
CScript result;
21+
22+
static map<string, opcodetype> mapOpNames;
23+
24+
if (mapOpNames.size() == 0)
25+
{
26+
for (int op = 0; op <= OP_NOP10; op++)
27+
{
28+
// Allow OP_RESERVED to get into mapOpNames
29+
if (op < OP_NOP && op != OP_RESERVED)
30+
continue;
31+
32+
const char* name = GetOpName((opcodetype)op);
33+
if (strcmp(name, "OP_UNKNOWN") == 0)
34+
continue;
35+
string strName(name);
36+
mapOpNames[strName] = (opcodetype)op;
37+
// Convenience: OP_ADD and just ADD are both recognized:
38+
replace_first(strName, "OP_", "");
39+
mapOpNames[strName] = (opcodetype)op;
40+
}
41+
}
42+
43+
vector<string> words;
44+
split(words, s, is_any_of(" \t\n"), token_compress_on);
45+
46+
BOOST_FOREACH(string w, words)
47+
{
48+
if (w.size() == 0)
49+
{
50+
// Empty string, ignore. (boost::split given '' will return one word)
51+
}
52+
else if (all(w, is_digit()) ||
53+
(starts_with(w, "-") && all(string(w.begin()+1, w.end()), is_digit())))
54+
{
55+
// Number
56+
int64_t n = atoi64(w);
57+
result << n;
58+
}
59+
else if (starts_with(w, "0x") && IsHex(string(w.begin()+2, w.end())))
60+
{
61+
// Raw hex data, inserted NOT pushed onto stack:
62+
std::vector<unsigned char> raw = ParseHex(string(w.begin()+2, w.end()));
63+
result.insert(result.end(), raw.begin(), raw.end());
64+
}
65+
else if (w.size() >= 2 && starts_with(w, "'") && ends_with(w, "'"))
66+
{
67+
// Single-quoted string, pushed as data. NOTE: this is poor-man's
68+
// parsing, spaces/tabs/newlines in single-quoted strings won't work.
69+
std::vector<unsigned char> value(w.begin()+1, w.end()-1);
70+
result << value;
71+
}
72+
else if (mapOpNames.count(w))
73+
{
74+
// opcode, e.g. OP_ADD or ADD:
75+
result << mapOpNames[w];
76+
}
77+
else
78+
{
79+
throw runtime_error("script parse error");
80+
}
81+
}
82+
83+
return result;
84+
}
885

986
bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx)
1087
{

src/test/script_tests.cpp

Lines changed: 1 addition & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "key.h"
1111
#include "keystore.h"
1212
#include "main.h"
13+
#include "core_io.h"
1314

1415
#include <fstream>
1516
#include <stdint.h>
@@ -36,76 +37,6 @@ extern uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo
3637

3738
static const unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC;
3839

39-
CScript
40-
ParseScript(string s)
41-
{
42-
CScript result;
43-
44-
static map<string, opcodetype> mapOpNames;
45-
46-
if (mapOpNames.size() == 0)
47-
{
48-
for (int op = 0; op <= OP_NOP10; op++)
49-
{
50-
// Allow OP_RESERVED to get into mapOpNames
51-
if (op < OP_NOP && op != OP_RESERVED)
52-
continue;
53-
54-
const char* name = GetOpName((opcodetype)op);
55-
if (strcmp(name, "OP_UNKNOWN") == 0)
56-
continue;
57-
string strName(name);
58-
mapOpNames[strName] = (opcodetype)op;
59-
// Convenience: OP_ADD and just ADD are both recognized:
60-
replace_first(strName, "OP_", "");
61-
mapOpNames[strName] = (opcodetype)op;
62-
}
63-
}
64-
65-
vector<string> words;
66-
split(words, s, is_any_of(" \t\n"), token_compress_on);
67-
68-
BOOST_FOREACH(string w, words)
69-
{
70-
if (w.size() == 0)
71-
{
72-
// Empty string, ignore. (boost::split given '' will return one word)
73-
}
74-
else if (all(w, is_digit()) ||
75-
(starts_with(w, "-") && all(string(w.begin()+1, w.end()), is_digit())))
76-
{
77-
// Number
78-
int64_t n = atoi64(w);
79-
result << n;
80-
}
81-
else if (starts_with(w, "0x") && IsHex(string(w.begin()+2, w.end())))
82-
{
83-
// Raw hex data, inserted NOT pushed onto stack:
84-
std::vector<unsigned char> raw = ParseHex(string(w.begin()+2, w.end()));
85-
result.insert(result.end(), raw.begin(), raw.end());
86-
}
87-
else if (w.size() >= 2 && starts_with(w, "'") && ends_with(w, "'"))
88-
{
89-
// Single-quoted string, pushed as data. NOTE: this is poor-man's
90-
// parsing, spaces/tabs/newlines in single-quoted strings won't work.
91-
std::vector<unsigned char> value(w.begin()+1, w.end()-1);
92-
result << value;
93-
}
94-
else if (mapOpNames.count(w))
95-
{
96-
// opcode, e.g. OP_ADD or ADD:
97-
result << mapOpNames[w];
98-
}
99-
else
100-
{
101-
BOOST_ERROR("Parse error: " << s);
102-
return CScript();
103-
}
104-
}
105-
106-
return result;
107-
}
108-
10940
Array
11041
read_json(const std::string& jsondata)
11142
{

src/test/transaction_tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "keystore.h"
1010
#include "main.h"
1111
#include "script.h"
12+
#include "core_io.h"
1213

1314
#include <map>
1415
#include <string>
@@ -24,7 +25,6 @@ using namespace boost::algorithm;
2425

2526
// In script_tests.cpp
2627
extern Array read_json(const std::string& jsondata);
27-
extern CScript ParseScript(string s);
2828

2929
unsigned int ParseFlags(string strFlags){
3030
unsigned int flags = 0;

0 commit comments

Comments
 (0)