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
|
#include "stflpp.h"
#include <cerrno>
#include <langinfo.h>
#include <mutex>
#include "exception.h"
#include "logger.h"
#include "utils.h"
namespace newsboat {
/*
* This is a wrapper around the low-level C functions of STFL.
* In order to make working with std::string easier, this wrapper
* was created. This is also useful for logging all stfl-related
* operations if necessary, and for working around bugs in STFL,
* especially related to stuff like multithreading fuckups.
*/
Stfl::Form::Form(const std::string& text)
: f(0)
{
ipool = stfl_ipool_create(
utils::translit(nl_langinfo(CODESET), "WCHAR_T").c_str());
if (!ipool) {
throw Exception(errno);
}
f = stfl_create(stfl_ipool_towc(ipool, text.c_str()));
if (!f) {
throw Exception(errno);
}
}
Stfl::Form::~Form()
{
if (f) {
stfl_free(f);
}
if (ipool) {
stfl_ipool_destroy(ipool);
}
}
std::string Stfl::Form::run(int timeout)
{
const auto event = stfl_ipool_fromwc(ipool, stfl_run(f, timeout));
if (event != nullptr) {
return std::string(event);
} else {
return "";
}
}
std::string Stfl::Form::get(const std::string& name)
{
const char* text = stfl_ipool_fromwc(
ipool, stfl_get(f, stfl_ipool_towc(ipool, name.c_str())));
std::string retval;
if (text) {
retval = text;
}
stfl_ipool_flush(ipool);
return retval;
}
void Stfl::Form::set(const std::string& name, const std::string& value)
{
stfl_set(f,
stfl_ipool_towc(ipool, name.c_str()),
stfl_ipool_towc(ipool, value.c_str()));
stfl_ipool_flush(ipool);
}
std::string Stfl::Form::get_focus()
{
const char* focus = stfl_ipool_fromwc(ipool, stfl_get_focus(f));
std::string retval;
if (focus) {
retval = focus;
}
stfl_ipool_flush(ipool);
return retval;
}
void Stfl::Form::set_focus(const std::string& name)
{
stfl_set_focus(f, stfl_ipool_towc(ipool, name.c_str()));
LOG(Level::DEBUG, "Stfl::Form::set_focus: %s", name);
}
void Stfl::Form::modify(const std::string& name,
const std::string& mode,
const std::string& text)
{
const wchar_t* wname, *wmode, *wtext;
wname = stfl_ipool_towc(ipool, name.c_str());
wmode = stfl_ipool_towc(ipool, mode.c_str());
wtext = stfl_ipool_towc(ipool, text.c_str());
stfl_modify(f, wname, wmode, wtext);
stfl_ipool_flush(ipool);
}
void Stfl::reset()
{
stfl_reset();
}
static std::mutex quote_mtx;
std::string Stfl::quote(const std::string& text)
{
std::lock_guard<std::mutex> lock(quote_mtx);
stfl_ipool* ipool = stfl_ipool_create(
utils::translit(nl_langinfo(CODESET), "WCHAR_T").c_str());
std::string retval = stfl_ipool_fromwc(
ipool, stfl_quote(stfl_ipool_towc(ipool, text.c_str())));
stfl_ipool_destroy(ipool);
return retval;
}
std::string Stfl::Form::dump(const std::string& name, const std::string& prefix,
int focus)
{
const char* text = stfl_ipool_fromwc(ipool,
stfl_dump(f,
stfl_ipool_towc(ipool, name.c_str()),
stfl_ipool_towc(ipool, prefix.c_str()),
focus));
std::string retval;
if (text) {
retval = text;
}
stfl_ipool_flush(ipool);
return retval;
}
} // namespace newsboat
|