Electroneum
Toggle main menu visibility
Loading...
Searching...
No Matches
readline_buffer.cpp
Go to the documentation of this file.
1
#include "
readline_buffer.h
"
2
#include <readline/readline.h>
3
#include <readline/history.h>
4
#include <iostream>
5
#include <boost/thread/mutex.hpp>
6
#include <boost/thread/lock_guard.hpp>
7
#include <boost/algorithm/string.hpp>
8
9
static
void
install_line_handler();
10
static
void
remove_line_handler();
11
12
static
boost::mutex sync_mutex;
13
static
rdln::linestatus
line_stat;
14
static
char
*the_line;
15
16
namespace
17
{
18
rdln::readline_buffer
* current = NULL;
19
}
20
21
rdln::suspend_readline::suspend_readline
()
22
: m_buffer(NULL), m_restart(
false
)
23
{
24
m_buffer = current;
25
if
(!m_buffer)
26
return
;
27
m_restart = m_buffer->is_running();
28
if
(m_restart)
29
m_buffer->stop();
30
}
31
32
rdln::suspend_readline::~suspend_readline
()
33
{
34
if
(!m_buffer)
35
return
;
36
if
(m_restart)
37
m_buffer->start();
38
}
39
40
std::vector<std::string>& rdln::readline_buffer::completion_commands()
41
{
42
static
std::vector<std::string> commands = {
"exit"
};
43
return
commands;
44
}
45
46
rdln::readline_buffer::readline_buffer
()
47
:
std
::stringbuf(), m_cout_buf(NULL), m_prompt_length(0)
48
{
49
current =
this
;
50
}
51
52
void
rdln::readline_buffer::start
()
53
{
54
if
(m_cout_buf != NULL)
55
return
;
56
m_cout_buf = std::cout.rdbuf();
57
std::cout.rdbuf(
this
);
58
install_line_handler();
59
}
60
61
void
rdln::readline_buffer::stop
()
62
{
63
if
(m_cout_buf == NULL)
64
return
;
65
std::cout.rdbuf(m_cout_buf);
66
m_cout_buf = NULL;
67
remove_line_handler();
68
}
69
70
rdln::linestatus
rdln::readline_buffer::get_line
(std::string& line)
const
71
{
72
boost::lock_guard<boost::mutex> lock(sync_mutex);
73
line_stat =
rdln::partial
;
74
rl_callback_read_char();
75
if
(line_stat ==
rdln::full
)
76
{
77
line = the_line;
78
free(the_line);
79
the_line = NULL;
80
}
81
return
line_stat;
82
}
83
84
void
rdln::readline_buffer::set_prompt
(
const
std::string& prompt)
85
{
86
if
(m_cout_buf == NULL)
87
return
;
88
boost::lock_guard<boost::mutex> lock(sync_mutex);
89
rl_set_prompt(std::string(m_prompt_length,
' '
).c_str());
90
rl_redisplay();
91
rl_set_prompt(prompt.c_str());
92
rl_redisplay();
93
m_prompt_length = prompt.size();
94
}
95
96
void
rdln::readline_buffer::add_completion
(
const
std::string& command)
97
{
98
if
(std::find(completion_commands().begin(), completion_commands().end(), command) != completion_commands().end())
99
return
;
100
completion_commands().push_back(command);
101
}
102
103
const
std::vector<std::string>&
rdln::readline_buffer::get_completions
()
104
{
105
return
completion_commands();
106
}
107
108
int
rdln::readline_buffer::sync
()
109
{
110
boost::lock_guard<boost::mutex> lock(sync_mutex);
111
#if RL_READLINE_VERSION < 0x0700
112
char
lbuf[2] = {0,0};
113
char
*line = NULL;
114
int
end = 0, point = 0;
115
#endif
116
117
if
(rl_end || (rl_prompt && *rl_prompt))
118
{
119
#if RL_READLINE_VERSION >= 0x0700
120
rl_clear_visible_line();
121
#else
122
line = rl_line_buffer;
123
end = rl_end;
124
point = rl_point;
125
rl_line_buffer = lbuf;
126
rl_end = 0;
127
rl_point = 0;
128
rl_save_prompt();
129
rl_redisplay();
130
#endif
131
}
132
133
do
134
{
135
m_cout_buf->sputc( this->sgetc() );
136
}
137
while
( this->snextc() != EOF );
138
139
#if RL_READLINE_VERSION < 0x0700
140
if
(end || (rl_prompt && *rl_prompt))
141
{
142
rl_restore_prompt();
143
rl_line_buffer = line;
144
rl_end = end;
145
rl_point = point;
146
}
147
#endif
148
rl_on_new_line();
149
rl_redisplay();
150
151
return
0;
152
}
153
154
static
void
handle_line(
char
* line)
155
{
156
bool
exit =
false
;
157
if
(line)
158
{
159
line_stat =
rdln::full
;
160
the_line = line;
161
std::string test_line = line;
162
boost::trim_right(test_line);
163
if
(!test_line.empty())
164
{
165
add_history(test_line.c_str());
166
history_set_pos(history_length);
167
if
(test_line ==
"exit"
|| test_line ==
"q"
)
168
exit =
true
;
169
}
170
}
else
171
/* EOF */
172
{
173
line_stat =
rdln::empty
;
174
exit =
true
;
175
}
176
rl_done = 1;
177
if
(exit)
178
rl_set_prompt(
""
);
179
return
;
180
}
181
182
static
char
* completion_matches(
const
char
* text,
int
state)
183
{
184
static
size_t
list_index;
185
static
size_t
len;
186
187
if
(state == 0)
188
{
189
list_index = 0;
190
len = strlen(text);
191
}
192
193
const
std::vector<std::string>& completions =
rdln::readline_buffer::get_completions
();
194
for
(; list_index<completions.size(); )
195
{
196
const
std::string& cmd = completions[list_index++];
197
if
(cmd.compare(0, len, text) == 0)
198
{
199
return
strdup(cmd.c_str());
200
}
201
}
202
203
return
NULL;
204
}
205
206
static
char
** attempted_completion(
const
char
* text,
int
start,
int
end)
207
{
208
rl_attempted_completion_over = 1;
209
return
rl_completion_matches(text, completion_matches);
210
}
211
212
static
void
install_line_handler()
213
{
214
rl_attempted_completion_function = attempted_completion;
215
rl_callback_handler_install(
""
, handle_line);
216
stifle_history(500);
217
}
218
219
static
void
remove_line_handler()
220
{
221
rl_replace_line(
""
, 0);
222
rl_set_prompt(
""
);
223
rl_redisplay();
224
rl_callback_handler_remove();
225
}
226
rdln::readline_buffer
Definition
readline_buffer.h:11
rdln::readline_buffer::get_completions
static const std::vector< std::string > & get_completions()
Definition
readline_buffer.cpp:103
rdln::readline_buffer::sync
virtual int sync()
Definition
readline_buffer.cpp:108
rdln::readline_buffer::set_prompt
void set_prompt(const std::string &prompt)
Definition
readline_buffer.cpp:84
rdln::readline_buffer::start
void start()
Definition
readline_buffer.cpp:52
rdln::readline_buffer::stop
void stop()
Definition
readline_buffer.cpp:61
rdln::readline_buffer::add_completion
static void add_completion(const std::string &command)
Definition
readline_buffer.cpp:96
rdln::readline_buffer::get_line
linestatus get_line(std::string &line) const
Definition
readline_buffer.cpp:70
rdln::readline_buffer::readline_buffer
readline_buffer()
Definition
readline_buffer.cpp:46
rdln::suspend_readline::~suspend_readline
~suspend_readline()
Definition
readline_buffer.cpp:32
rdln::suspend_readline::suspend_readline
suspend_readline()
Definition
readline_buffer.cpp:21
rdln::linestatus
linestatus
Definition
readline_buffer.h:9
rdln::partial
@ partial
Definition
readline_buffer.h:9
rdln::full
@ full
Definition
readline_buffer.h:9
rdln::empty
@ empty
Definition
readline_buffer.h:9
std
STL namespace.
readline_buffer.h
false
#define false
contrib
epee
src
readline_buffer.cpp
Generated on
for Electroneum by
1.17.0