1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
#include "py_eval.h"
#include "journal.h"
#include "error.h"
#include "acconf.h"
#include <sstream>
#include <map>
namespace {
bool python_initialized = false;
bool module_initialized = false;
}
void export_amount();
void export_balance();
void export_value();
void export_journal();
void export_parser();
void export_textual();
void export_binary();
void export_qif();
#ifdef HAVE_XMLPARSE
void export_xml();
void export_gnucash();
#endif
#ifdef HAVE_LIBOFX
void export_ofx();
#endif
void export_option();
void export_config();
void export_walk();
void export_format();
void export_valexpr();
void export_datetime();
void export_derive();
void export_reconcile();
void export_emacs();
void initialize_ledger_for_python()
{
export_amount();
export_balance();
export_value();
export_journal();
export_parser();
export_textual();
export_binary();
export_qif();
#ifdef HAVE_XMLPARSE
export_xml();
export_gnucash();
#endif
#ifdef HAVE_LIBOFX
export_ofx();
#endif
export_option();
export_config();
export_walk();
export_format();
export_valexpr();
export_datetime();
export_derive();
export_reconcile();
export_emacs();
module_initialized = true;
}
namespace ledger {
static struct python_main_t
{
handle<> mmodule;
dict nspace;
python_main_t()
: mmodule(borrowed(PyImport_AddModule("__main__"))),
nspace(handle<>(borrowed(PyModule_GetDict(mmodule.get())))) {}
}
* python_main = NULL;
struct python_run
{
object result;
python_run(const std::string& str, int input_mode)
: result(handle<>(borrowed(PyRun_String(str.c_str(), input_mode,
python_main->nspace.ptr(),
python_main->nspace.ptr())))) {}
operator object() {
return result;
}
};
static struct cleanup_python {
~cleanup_python() {
if (python_main) {
delete python_main;
python_main = NULL;
}
if (python_initialized)
Py_Finalize();
}
} _cleanup;
void init_python()
{
if (! module_initialized) {
Py_Initialize();
python_initialized = true;
detail::init_module("ledger", &initialize_ledger_for_python);
}
python_main = new python_main_t;
}
object python_eval(std::istream& in, py_eval_mode_t mode)
{
if (! python_initialized)
init_python();
bool first = true;
std::string buffer;
buffer.reserve(4096);
while (! in.eof()) {
char buf[256];
in.getline(buf, 255);
if (buf[0] == '!')
break;
if (first)
first = false;
else
buffer += "\n";
buffer += buf;
}
try {
int input_mode;
switch (mode) {
case PY_EVAL_EXPR: input_mode = Py_eval_input; break;
case PY_EVAL_STMT: input_mode = Py_single_input; break;
case PY_EVAL_MULTI: input_mode = Py_file_input; break;
}
assert(Py_IsInitialized());
return python_run(buffer, input_mode);
}
catch(const boost::python::error_already_set&) {
PyErr_Print();
throw error("Evaluating Python code");
}
}
object python_eval(const std::string& str, py_eval_mode_t mode)
{
std::istringstream stream(str);
return python_eval(stream, mode);
}
object python_eval(const char * c_str, py_eval_mode_t mode)
{
std::string str(c_str);
return python_eval(str, mode);
}
} // namespace ledger
|