Mercurial > hg > CbC > CbC_llvm
comparison lldb/source/Host/common/Editline.cpp @ 173:0572611fdcc8 llvm10 llvm12
reorgnization done
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 25 May 2020 11:55:54 +0900 |
parents | 1d019706d866 |
children | 2e18cbf3894f |
comparison
equal
deleted
inserted
replaced
172:9fbae9c8bf63 | 173:0572611fdcc8 |
---|---|
33 // may benefit from something similar if issues arise. The libedit library | 33 // may benefit from something similar if issues arise. The libedit library |
34 // doesn't explicitly initialize the curses termcap library, which it gets away | 34 // doesn't explicitly initialize the curses termcap library, which it gets away |
35 // with until TERM is set to VT100 where it stumbles over an implementation | 35 // with until TERM is set to VT100 where it stumbles over an implementation |
36 // assumption that may not exist on other platforms. The setupterm() function | 36 // assumption that may not exist on other platforms. The setupterm() function |
37 // would normally require headers that don't work gracefully in this context, | 37 // would normally require headers that don't work gracefully in this context, |
38 // so the function declaraction has been hoisted here. | 38 // so the function declaration has been hoisted here. |
39 #if defined(__APPLE__) | 39 #if defined(__APPLE__) |
40 extern "C" { | 40 extern "C" { |
41 int setupterm(char *term, int fildes, int *errret); | 41 int setupterm(char *term, int fildes, int *errret); |
42 } | 42 } |
43 #define USE_SETUPTERM_WORKAROUND | 43 #define USE_SETUPTERM_WORKAROUND |
97 return true; | 97 return true; |
98 } | 98 } |
99 | 99 |
100 static int GetOperation(HistoryOperation op) { | 100 static int GetOperation(HistoryOperation op) { |
101 // The naming used by editline for the history operations is counter | 101 // The naming used by editline for the history operations is counter |
102 // intuitive to how it's used here. | 102 // intuitive to how it's used in LLDB's editline implementation. |
103 // | |
104 // - The H_LAST returns the oldest entry in the history. | |
103 // | 105 // |
104 // - The H_PREV operation returns the previous element in the history, which | 106 // - The H_PREV operation returns the previous element in the history, which |
105 // is newer than the current one. | 107 // is newer than the current one. |
106 // | 108 // |
109 // - The H_CURR returns the current entry in the history. | |
110 // | |
107 // - The H_NEXT operation returns the next element in the history, which is | 111 // - The H_NEXT operation returns the next element in the history, which is |
108 // older than the current one. | 112 // older than the current one. |
113 // | |
114 // - The H_FIRST returns the most recent entry in the history. | |
109 // | 115 // |
110 // The naming of the enum entries match the semantic meaning. | 116 // The naming of the enum entries match the semantic meaning. |
111 switch(op) { | 117 switch(op) { |
112 case HistoryOperation::Oldest: | 118 case HistoryOperation::Oldest: |
113 return H_FIRST; | 119 return H_LAST; |
114 case HistoryOperation::Older: | 120 case HistoryOperation::Older: |
115 return H_NEXT; | 121 return H_NEXT; |
116 case HistoryOperation::Current: | 122 case HistoryOperation::Current: |
117 return H_CURR; | 123 return H_CURR; |
118 case HistoryOperation::Newer: | 124 case HistoryOperation::Newer: |
119 return H_PREV; | 125 return H_PREV; |
120 case HistoryOperation::Newest: | 126 case HistoryOperation::Newest: |
121 return H_LAST; | 127 return H_FIRST; |
122 } | 128 } |
123 llvm_unreachable("Fully covered switch!"); | 129 llvm_unreachable("Fully covered switch!"); |
124 } | 130 } |
125 | 131 |
126 | 132 |
136 std::vector<EditLineStringType> result; | 142 std::vector<EditLineStringType> result; |
137 size_t start = 0; | 143 size_t start = 0; |
138 while (start < input.length()) { | 144 while (start < input.length()) { |
139 size_t end = input.find('\n', start); | 145 size_t end = input.find('\n', start); |
140 if (end == std::string::npos) { | 146 if (end == std::string::npos) { |
141 result.insert(result.end(), input.substr(start)); | 147 result.push_back(input.substr(start)); |
142 break; | 148 break; |
143 } | 149 } |
144 result.insert(result.end(), input.substr(start, end - start)); | 150 result.push_back(input.substr(start, end - start)); |
145 start = end + 1; | 151 start = end + 1; |
146 } | 152 } |
147 return result; | 153 return result; |
148 } | 154 } |
149 | 155 |
294 } | 300 } |
295 | 301 |
296 // Editline private methods | 302 // Editline private methods |
297 | 303 |
298 void Editline::SetBaseLineNumber(int line_number) { | 304 void Editline::SetBaseLineNumber(int line_number) { |
299 std::stringstream line_number_stream; | |
300 line_number_stream << line_number; | |
301 m_base_line_number = line_number; | 305 m_base_line_number = line_number; |
302 m_line_number_digits = | 306 m_line_number_digits = |
303 std::max(3, (int)line_number_stream.str().length() + 1); | 307 std::max<int>(3, std::to_string(line_number).length() + 1); |
304 } | 308 } |
305 | 309 |
306 std::string Editline::PromptForIndex(int line_index) { | 310 std::string Editline::PromptForIndex(int line_index) { |
307 bool use_line_numbers = m_multiline_enabled && m_base_line_number > 0; | 311 bool use_line_numbers = m_multiline_enabled && m_base_line_number > 0; |
308 std::string prompt = m_set_prompt; | 312 std::string prompt = m_set_prompt; |
309 if (use_line_numbers && prompt.length() == 0) { | 313 if (use_line_numbers && prompt.length() == 0) |
310 prompt = ": "; | 314 prompt = ": "; |
311 } | |
312 std::string continuation_prompt = prompt; | 315 std::string continuation_prompt = prompt; |
313 if (m_set_continuation_prompt.length() > 0) { | 316 if (m_set_continuation_prompt.length() > 0) { |
314 continuation_prompt = m_set_continuation_prompt; | 317 continuation_prompt = m_set_continuation_prompt; |
315 | 318 |
316 // Ensure that both prompts are the same length through space padding | 319 // Ensure that both prompts are the same length through space padding |
421 fprintf(m_output_file, "\n"); | 424 fprintf(m_output_file, "\n"); |
422 } | 425 } |
423 } | 426 } |
424 | 427 |
425 int Editline::CountRowsForLine(const EditLineStringType &content) { | 428 int Editline::CountRowsForLine(const EditLineStringType &content) { |
426 auto prompt = | 429 std::string prompt = |
427 PromptForIndex(0); // Prompt width is constant during an edit session | 430 PromptForIndex(0); // Prompt width is constant during an edit session |
428 int line_length = (int)(content.length() + prompt.length()); | 431 int line_length = (int)(content.length() + prompt.length()); |
429 return (line_length / m_terminal_width) + 1; | 432 return (line_length / m_terminal_width) + 1; |
430 } | 433 } |
431 | 434 |
555 // Read an actual character | 558 // Read an actual character |
556 while (true) { | 559 while (true) { |
557 lldb::ConnectionStatus status = lldb::eConnectionStatusSuccess; | 560 lldb::ConnectionStatus status = lldb::eConnectionStatusSuccess; |
558 char ch = 0; | 561 char ch = 0; |
559 | 562 |
563 if (m_terminal_size_has_changed) | |
564 ApplyTerminalSizeChange(); | |
565 | |
560 // This mutex is locked by our caller (GetLine). Unlock it while we read a | 566 // This mutex is locked by our caller (GetLine). Unlock it while we read a |
561 // character (blocking operation), so we do not hold the mutex | 567 // character (blocking operation), so we do not hold the mutex |
562 // indefinitely. This gives a chance for someone to interrupt us. After | 568 // indefinitely. This gives a chance for someone to interrupt us. After |
563 // Read returns, immediately lock the mutex again and check if we were | 569 // Read returns, immediately lock the mutex again and check if we were |
564 // interrupted. | 570 // interrupted. |
1047 el_end(m_editline); | 1053 el_end(m_editline); |
1048 } | 1054 } |
1049 | 1055 |
1050 m_editline = | 1056 m_editline = |
1051 el_init(m_editor_name.c_str(), m_input_file, m_output_file, m_error_file); | 1057 el_init(m_editor_name.c_str(), m_input_file, m_output_file, m_error_file); |
1052 TerminalSizeChanged(); | 1058 ApplyTerminalSizeChange(); |
1053 | 1059 |
1054 if (m_history_sp && m_history_sp->IsValid()) { | 1060 if (m_history_sp && m_history_sp->IsValid()) { |
1055 if (!m_history_sp->Load()) { | 1061 if (!m_history_sp->Load()) { |
1056 fputs("Could not load history file\n.", m_output_file); | 1062 fputs("Could not load history file\n.", m_output_file); |
1057 } | 1063 } |
1300 void Editline::SetContinuationPrompt(const char *continuation_prompt) { | 1306 void Editline::SetContinuationPrompt(const char *continuation_prompt) { |
1301 m_set_continuation_prompt = | 1307 m_set_continuation_prompt = |
1302 continuation_prompt == nullptr ? "" : continuation_prompt; | 1308 continuation_prompt == nullptr ? "" : continuation_prompt; |
1303 } | 1309 } |
1304 | 1310 |
1305 void Editline::TerminalSizeChanged() { | 1311 void Editline::TerminalSizeChanged() { m_terminal_size_has_changed = 1; } |
1306 if (m_editline != nullptr) { | 1312 |
1307 el_resize(m_editline); | 1313 void Editline::ApplyTerminalSizeChange() { |
1308 int columns; | 1314 if (!m_editline) |
1309 // This function is documenting as taking (const char *, void *) for the | 1315 return; |
1310 // vararg part, but in reality in was consuming arguments until the first | 1316 |
1311 // null pointer. This was fixed in libedit in April 2019 | 1317 m_terminal_size_has_changed = 0; |
1312 // <http://mail-index.netbsd.org/source-changes/2019/04/26/msg105454.html>, | 1318 el_resize(m_editline); |
1313 // but we're keeping the workaround until a version with that fix is more | 1319 int columns; |
1314 // widely available. | 1320 // This function is documenting as taking (const char *, void *) for the |
1315 if (el_get(m_editline, EL_GETTC, "co", &columns, nullptr) == 0) { | 1321 // vararg part, but in reality in was consuming arguments until the first |
1316 m_terminal_width = columns; | 1322 // null pointer. This was fixed in libedit in April 2019 |
1317 if (m_current_line_rows != -1) { | 1323 // <http://mail-index.netbsd.org/source-changes/2019/04/26/msg105454.html>, |
1318 const LineInfoW *info = el_wline(m_editline); | 1324 // but we're keeping the workaround until a version with that fix is more |
1319 int lineLength = | 1325 // widely available. |
1320 (int)((info->lastchar - info->buffer) + GetPromptWidth()); | 1326 if (el_get(m_editline, EL_GETTC, "co", &columns, nullptr) == 0) { |
1321 m_current_line_rows = (lineLength / columns) + 1; | 1327 m_terminal_width = columns; |
1322 } | 1328 if (m_current_line_rows != -1) { |
1323 } else { | 1329 const LineInfoW *info = el_wline(m_editline); |
1324 m_terminal_width = INT_MAX; | 1330 int lineLength = |
1325 m_current_line_rows = 1; | 1331 (int)((info->lastchar - info->buffer) + GetPromptWidth()); |
1326 } | 1332 m_current_line_rows = (lineLength / columns) + 1; |
1333 } | |
1334 } else { | |
1335 m_terminal_width = INT_MAX; | |
1336 m_current_line_rows = 1; | |
1327 } | 1337 } |
1328 } | 1338 } |
1329 | 1339 |
1330 const char *Editline::GetPrompt() { return m_set_prompt.c_str(); } | 1340 const char *Editline::GetPrompt() { return m_set_prompt.c_str(); } |
1331 | 1341 |