Skip to content

Commit de1a1c4

Browse files
committed
[lldb] Use Locale to convert between std::wstring and std::string (NFC)
The codecvt header has been deprecated in C++17. Use locale to convert between std::string and std::wstring in Editline.
1 parent 92ad039 commit de1a1c4

File tree

2 files changed

+47
-12
lines changed

2 files changed

+47
-12
lines changed

lldb/include/lldb/Host/Editline.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,6 @@
3030

3131
#include "lldb/Host/Config.h"
3232

33-
#if LLDB_EDITLINE_USE_WCHAR
34-
#include <codecvt>
35-
#endif
3633
#include <locale>
3734
#include <sstream>
3835
#include <vector>
@@ -366,9 +363,6 @@ class Editline {
366363
void SetEditLinePromptCallback(EditlinePromptCallbackType callbackFn);
367364
void SetGetCharacterFunction(EditlineGetCharCallbackType callbackFn);
368365

369-
#if LLDB_EDITLINE_USE_WCHAR
370-
std::wstring_convert<std::codecvt_utf8<wchar_t>> m_utf8conv;
371-
#endif
372366
::EditLine *m_editline = nullptr;
373367
EditlineHistorySP m_history_sp;
374368
bool m_in_history = false;

lldb/source/Host/common/Editline.cpp

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,46 @@ using namespace lldb_private::line_editor;
7676

7777
#endif // #if LLDB_EDITLINE_USE_WCHAR
7878

79+
#if LLDB_EDITLINE_USE_WCHAR
80+
std::string ToBytes(const std::wstring &in) {
81+
static std::locale locale("C.UTF-8");
82+
static const auto &cvt =
83+
std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t>>(locale);
84+
85+
const size_t length = in.length();
86+
std::string output(length + 1, 0x0);
87+
88+
std::mbstate_t mbs{};
89+
const wchar_t *in_next;
90+
char *out_next;
91+
92+
if (cvt.out(mbs, in.data(), in.data() + length + 1, in_next, output.data(),
93+
output.data() + output.length() + 1,
94+
out_next) == std::codecvt_base::ok)
95+
return output;
96+
return {};
97+
}
98+
99+
std::wstring FromBytes(const std::string &in) {
100+
static std::locale locale("C.UTF-8");
101+
static const auto &cvt =
102+
std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t>>(locale);
103+
104+
const size_t length = in.length();
105+
std::wstring output(length + 1, 0x0);
106+
107+
std::mbstate_t mbs{};
108+
const char *in_next;
109+
wchar_t *out_next;
110+
111+
if (cvt.in(mbs, in.data(), in.data() + length + 1, in_next, output.data(),
112+
output.data() + output.length() + 1,
113+
out_next) == std::codecvt_base::ok)
114+
return output;
115+
return {};
116+
}
117+
#endif
118+
79119
bool IsOnlySpaces(const EditLineStringType &content) {
80120
for (wchar_t ch : content) {
81121
if (ch != EditLineCharType(' '))
@@ -444,7 +484,7 @@ StringList Editline::GetInputAsStringList(int line_count) {
444484
if (line_count == 0)
445485
break;
446486
#if LLDB_EDITLINE_USE_WCHAR
447-
lines.AppendString(m_utf8conv.to_bytes(line));
487+
lines.AppendString(ToBytes(line));
448488
#else
449489
lines.AppendString(line);
450490
#endif
@@ -636,7 +676,7 @@ unsigned char Editline::BreakLineCommand(int ch) {
636676
if (m_fix_indentation_callback) {
637677
StringList lines = GetInputAsStringList(m_current_line_index + 1);
638678
#if LLDB_EDITLINE_USE_WCHAR
639-
lines.AppendString(m_utf8conv.to_bytes(new_line_fragment));
679+
lines.AppendString(ToBytes(new_line_fragment));
640680
#else
641681
lines.AppendString(new_line_fragment);
642682
#endif
@@ -685,7 +725,7 @@ unsigned char Editline::EndOrAddLineCommand(int ch) {
685725
for (unsigned index = 0; index < lines.GetSize(); index++) {
686726
#if LLDB_EDITLINE_USE_WCHAR
687727
m_input_lines.insert(m_input_lines.end(),
688-
m_utf8conv.from_bytes(lines[index]));
728+
FromBytes(lines[index]));
689729
#else
690730
m_input_lines.insert(m_input_lines.end(), lines[index]);
691731
#endif
@@ -869,7 +909,7 @@ unsigned char Editline::FixIndentationCommand(int ch) {
869909
currentLine = currentLine.erase(0, -indent_correction);
870910
}
871911
#if LLDB_EDITLINE_USE_WCHAR
872-
m_input_lines[m_current_line_index] = m_utf8conv.from_bytes(currentLine);
912+
m_input_lines[m_current_line_index] = FromBytes(currentLine);
873913
#else
874914
m_input_lines[m_current_line_index] = currentLine;
875915
#endif
@@ -1502,7 +1542,7 @@ bool Editline::GetLine(std::string &line, bool &interrupted) {
15021542
} else {
15031543
m_history_sp->Enter(input);
15041544
#if LLDB_EDITLINE_USE_WCHAR
1505-
line = m_utf8conv.to_bytes(SplitLines(input)[0]);
1545+
line = ToBytes(SplitLines(input)[0]);
15061546
#else
15071547
line = SplitLines(input)[0];
15081548
#endif
@@ -1574,7 +1614,8 @@ bool Editline::CompleteCharacter(char ch, EditLineGetCharType &out) {
15741614
out = (unsigned char)ch;
15751615
return true;
15761616
#else
1577-
std::codecvt_utf8<wchar_t> cvt;
1617+
std::locale locale("C.UTF-8");
1618+
const auto &cvt = std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t>>(locale);
15781619
llvm::SmallString<4> input;
15791620
for (;;) {
15801621
const char *from_next;

0 commit comments

Comments
 (0)