Mercurial > hg > CbC > CbC_llvm
comparison lldb/source/Host/common/Editline.cpp @ 236:c4bab56944e8 llvm-original
LLVM 16
author | kono |
---|---|
date | Wed, 09 Nov 2022 17:45:10 +0900 |
parents | 79ff65ed7e25 |
children | 1f2b6ac9f198 |
comparison
equal
deleted
inserted
replaced
232:70dce7da266c | 236:c4bab56944e8 |
---|---|
203 class EditlineHistory { | 203 class EditlineHistory { |
204 private: | 204 private: |
205 // Use static GetHistory() function to get a EditlineHistorySP to one of | 205 // Use static GetHistory() function to get a EditlineHistorySP to one of |
206 // these objects | 206 // these objects |
207 EditlineHistory(const std::string &prefix, uint32_t size, bool unique_entries) | 207 EditlineHistory(const std::string &prefix, uint32_t size, bool unique_entries) |
208 : m_history(nullptr), m_event(), m_prefix(prefix), m_path() { | 208 : m_prefix(prefix) { |
209 m_history = history_winit(); | 209 m_history = history_winit(); |
210 history_w(m_history, &m_event, H_SETSIZE, size); | 210 history_w(m_history, &m_event, H_SETSIZE, size); |
211 if (unique_entries) | 211 if (unique_entries) |
212 history_w(m_history, &m_event, H_SETUNIQUE, 1); | 212 history_w(m_history, &m_event, H_SETUNIQUE, 1); |
213 } | 213 } |
296 } | 296 } |
297 return false; | 297 return false; |
298 } | 298 } |
299 | 299 |
300 protected: | 300 protected: |
301 HistoryW *m_history; // The history object | 301 /// The history object. |
302 HistEventW m_event; // The history event needed to contain all history events | 302 HistoryW *m_history = nullptr; |
303 std::string m_prefix; // The prefix name (usually the editline program name) | 303 /// The history event needed to contain all history events. |
304 // to use when loading/saving history | 304 HistEventW m_event; |
305 std::string m_path; // Path to the history file | 305 /// The prefix name (usually the editline program name) to use when |
306 /// loading/saving history. | |
307 std::string m_prefix; | |
308 /// Path to the history file. | |
309 std::string m_path; | |
306 }; | 310 }; |
307 } | 311 } |
308 } | 312 } |
309 | 313 |
310 // Editline private methods | 314 // Editline private methods |
1004 if (results.size() == 1) { | 1008 if (results.size() == 1) { |
1005 CompletionResult::Completion completion = results.front(); | 1009 CompletionResult::Completion completion = results.front(); |
1006 switch (completion.GetMode()) { | 1010 switch (completion.GetMode()) { |
1007 case CompletionMode::Normal: { | 1011 case CompletionMode::Normal: { |
1008 std::string to_add = completion.GetCompletion(); | 1012 std::string to_add = completion.GetCompletion(); |
1009 to_add = to_add.substr(request.GetCursorArgumentPrefix().size()); | |
1010 // Terminate the current argument with a quote if it started with a quote. | 1013 // Terminate the current argument with a quote if it started with a quote. |
1011 if (!request.GetParsedLine().empty() && request.GetParsedArg().IsQuoted()) | 1014 if (!request.GetParsedLine().empty() && request.GetParsedArg().IsQuoted()) |
1012 to_add.push_back(request.GetParsedArg().GetQuoteChar()); | 1015 to_add.push_back(request.GetParsedArg().GetQuoteChar()); |
1013 to_add.push_back(' '); | 1016 to_add.push_back(' '); |
1017 el_deletestr(m_editline, request.GetCursorArgumentPrefix().size()); | |
1014 el_insertstr(m_editline, to_add.c_str()); | 1018 el_insertstr(m_editline, to_add.c_str()); |
1015 // Clear all the autosuggestion parts if the only single space can be completed. | 1019 // Clear all the autosuggestion parts if the only single space can be completed. |
1016 if (to_add == " ") | 1020 if (to_add == " ") |
1017 return CC_REDISPLAY; | 1021 return CC_REDISPLAY; |
1018 return CC_REFRESH; | 1022 return CC_REFRESH; |
1074 | 1078 |
1075 const LineInfo *line_info = el_line(m_editline); | 1079 const LineInfo *line_info = el_line(m_editline); |
1076 llvm::StringRef line(line_info->buffer, | 1080 llvm::StringRef line(line_info->buffer, |
1077 line_info->lastchar - line_info->buffer); | 1081 line_info->lastchar - line_info->buffer); |
1078 | 1082 |
1083 const char *ansi_prefix = | |
1084 m_color_prompts ? m_suggestion_ansi_prefix.c_str() : ""; | |
1085 const char *ansi_suffix = | |
1086 m_color_prompts ? m_suggestion_ansi_suffix.c_str() : ""; | |
1087 | |
1079 if (llvm::Optional<std::string> to_add = m_suggestion_callback(line)) { | 1088 if (llvm::Optional<std::string> to_add = m_suggestion_callback(line)) { |
1080 std::string to_add_color = ANSI_FAINT + to_add.getValue() + ANSI_UNFAINT; | 1089 std::string to_add_color = ansi_prefix + to_add.value() + ansi_suffix; |
1081 fputs(typed.c_str(), m_output_file); | 1090 fputs(typed.c_str(), m_output_file); |
1082 fputs(to_add_color.c_str(), m_output_file); | 1091 fputs(to_add_color.c_str(), m_output_file); |
1083 size_t new_autosuggestion_size = line.size() + to_add->length(); | 1092 size_t new_autosuggestion_size = line.size() + to_add->length(); |
1084 // Print spaces to hide any remains of a previous longer autosuggestion. | 1093 // Print spaces to hide any remains of a previous longer autosuggestion. |
1085 if (new_autosuggestion_size < m_previous_autosuggestion_size) { | 1094 if (new_autosuggestion_size < m_previous_autosuggestion_size) { |
1365 el_get(editline, EL_CLIENTDATA, &editor); | 1374 el_get(editline, EL_CLIENTDATA, &editor); |
1366 return editor; | 1375 return editor; |
1367 } | 1376 } |
1368 | 1377 |
1369 Editline::Editline(const char *editline_name, FILE *input_file, | 1378 Editline::Editline(const char *editline_name, FILE *input_file, |
1370 FILE *output_file, FILE *error_file, bool color_prompts) | 1379 FILE *output_file, FILE *error_file, |
1380 std::recursive_mutex &output_mutex, bool color_prompts) | |
1371 : m_editor_status(EditorStatus::Complete), m_color_prompts(color_prompts), | 1381 : m_editor_status(EditorStatus::Complete), m_color_prompts(color_prompts), |
1372 m_input_file(input_file), m_output_file(output_file), | 1382 m_input_file(input_file), m_output_file(output_file), |
1373 m_error_file(error_file), m_input_connection(fileno(input_file), false) { | 1383 m_error_file(error_file), m_input_connection(fileno(input_file), false), |
1384 m_output_mutex(output_mutex) { | |
1374 // Get a shared history instance | 1385 // Get a shared history instance |
1375 m_editor_name = (editline_name == nullptr) ? "lldb-tmp" : editline_name; | 1386 m_editor_name = (editline_name == nullptr) ? "lldb-tmp" : editline_name; |
1376 m_history_sp = EditlineHistory::GetHistory(m_editor_name); | 1387 m_history_sp = EditlineHistory::GetHistory(m_editor_name); |
1377 | 1388 |
1378 #ifdef USE_SETUPTERM_WORKAROUND | 1389 #ifdef USE_SETUPTERM_WORKAROUND |
1379 if (m_output_file) { | 1390 if (m_output_file) { |
1380 const int term_fd = fileno(m_output_file); | 1391 const int term_fd = fileno(m_output_file); |
1381 if (term_fd != -1) { | 1392 if (term_fd != -1) { |
1382 static std::mutex *g_init_terminal_fds_mutex_ptr = nullptr; | 1393 static std::recursive_mutex *g_init_terminal_fds_mutex_ptr = nullptr; |
1383 static std::set<int> *g_init_terminal_fds_ptr = nullptr; | 1394 static std::set<int> *g_init_terminal_fds_ptr = nullptr; |
1384 static llvm::once_flag g_once_flag; | 1395 static llvm::once_flag g_once_flag; |
1385 llvm::call_once(g_once_flag, [&]() { | 1396 llvm::call_once(g_once_flag, [&]() { |
1386 g_init_terminal_fds_mutex_ptr = | 1397 g_init_terminal_fds_mutex_ptr = |
1387 new std::mutex(); // NOTE: Leak to avoid C++ destructor chain issues | 1398 new std::recursive_mutex(); // NOTE: Leak to avoid C++ destructor |
1399 // chain issues | |
1388 g_init_terminal_fds_ptr = new std::set<int>(); // NOTE: Leak to avoid | 1400 g_init_terminal_fds_ptr = new std::set<int>(); // NOTE: Leak to avoid |
1389 // C++ destructor chain | 1401 // C++ destructor chain |
1390 // issues | 1402 // issues |
1391 }); | 1403 }); |
1392 | 1404 |
1393 // We must make sure to initialize the terminal a given file descriptor | 1405 // We must make sure to initialize the terminal a given file descriptor |
1394 // only once. If we do this multiple times, we start leaking memory. | 1406 // only once. If we do this multiple times, we start leaking memory. |
1395 std::lock_guard<std::mutex> guard(*g_init_terminal_fds_mutex_ptr); | 1407 std::lock_guard<std::recursive_mutex> guard( |
1408 *g_init_terminal_fds_mutex_ptr); | |
1396 if (g_init_terminal_fds_ptr->find(term_fd) == | 1409 if (g_init_terminal_fds_ptr->find(term_fd) == |
1397 g_init_terminal_fds_ptr->end()) { | 1410 g_init_terminal_fds_ptr->end()) { |
1398 g_init_terminal_fds_ptr->insert(term_fd); | 1411 g_init_terminal_fds_ptr->insert(term_fd); |
1399 setupterm((char *)0, term_fd, (int *)0); | 1412 setupterm((char *)0, term_fd, (int *)0); |
1400 } | 1413 } |
1462 | 1475 |
1463 uint32_t Editline::GetCurrentLine() { return m_current_line_index; } | 1476 uint32_t Editline::GetCurrentLine() { return m_current_line_index; } |
1464 | 1477 |
1465 bool Editline::Interrupt() { | 1478 bool Editline::Interrupt() { |
1466 bool result = true; | 1479 bool result = true; |
1467 std::lock_guard<std::mutex> guard(m_output_mutex); | 1480 std::lock_guard<std::recursive_mutex> guard(m_output_mutex); |
1468 if (m_editor_status == EditorStatus::Editing) { | 1481 if (m_editor_status == EditorStatus::Editing) { |
1469 fprintf(m_output_file, "^C\n"); | 1482 fprintf(m_output_file, "^C\n"); |
1470 result = m_input_connection.InterruptRead(); | 1483 result = m_input_connection.InterruptRead(); |
1471 } | 1484 } |
1472 m_editor_status = EditorStatus::Interrupted; | 1485 m_editor_status = EditorStatus::Interrupted; |
1473 return result; | 1486 return result; |
1474 } | 1487 } |
1475 | 1488 |
1476 bool Editline::Cancel() { | 1489 bool Editline::Cancel() { |
1477 bool result = true; | 1490 bool result = true; |
1478 std::lock_guard<std::mutex> guard(m_output_mutex); | 1491 std::lock_guard<std::recursive_mutex> guard(m_output_mutex); |
1479 if (m_editor_status == EditorStatus::Editing) { | 1492 if (m_editor_status == EditorStatus::Editing) { |
1480 MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockStart); | 1493 MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockStart); |
1481 fprintf(m_output_file, ANSI_CLEAR_BELOW); | 1494 fprintf(m_output_file, ANSI_CLEAR_BELOW); |
1482 result = m_input_connection.InterruptRead(); | 1495 result = m_input_connection.InterruptRead(); |
1483 } | 1496 } |
1488 bool Editline::GetLine(std::string &line, bool &interrupted) { | 1501 bool Editline::GetLine(std::string &line, bool &interrupted) { |
1489 ConfigureEditor(false); | 1502 ConfigureEditor(false); |
1490 m_input_lines = std::vector<EditLineStringType>(); | 1503 m_input_lines = std::vector<EditLineStringType>(); |
1491 m_input_lines.insert(m_input_lines.begin(), EditLineConstString("")); | 1504 m_input_lines.insert(m_input_lines.begin(), EditLineConstString("")); |
1492 | 1505 |
1493 std::lock_guard<std::mutex> guard(m_output_mutex); | 1506 std::lock_guard<std::recursive_mutex> guard(m_output_mutex); |
1494 | 1507 |
1495 lldbassert(m_editor_status != EditorStatus::Editing); | 1508 lldbassert(m_editor_status != EditorStatus::Editing); |
1496 if (m_editor_status == EditorStatus::Interrupted) { | 1509 if (m_editor_status == EditorStatus::Interrupted) { |
1497 m_editor_status = EditorStatus::Complete; | 1510 m_editor_status = EditorStatus::Complete; |
1498 interrupted = true; | 1511 interrupted = true; |
1533 // of input | 1546 // of input |
1534 SetBaseLineNumber(first_line_number); | 1547 SetBaseLineNumber(first_line_number); |
1535 m_input_lines = std::vector<EditLineStringType>(); | 1548 m_input_lines = std::vector<EditLineStringType>(); |
1536 m_input_lines.insert(m_input_lines.begin(), EditLineConstString("")); | 1549 m_input_lines.insert(m_input_lines.begin(), EditLineConstString("")); |
1537 | 1550 |
1538 std::lock_guard<std::mutex> guard(m_output_mutex); | 1551 std::lock_guard<std::recursive_mutex> guard(m_output_mutex); |
1539 // Begin the line editing loop | 1552 // Begin the line editing loop |
1540 DisplayInput(); | 1553 DisplayInput(); |
1541 SetCurrentLine(0); | 1554 SetCurrentLine(0); |
1542 MoveCursor(CursorLocation::BlockEnd, CursorLocation::BlockStart); | 1555 MoveCursor(CursorLocation::BlockEnd, CursorLocation::BlockStart); |
1543 m_editor_status = EditorStatus::Editing; | 1556 m_editor_status = EditorStatus::Editing; |
1552 el_wgets(m_editline, &count); | 1565 el_wgets(m_editline, &count); |
1553 } | 1566 } |
1554 | 1567 |
1555 interrupted = m_editor_status == EditorStatus::Interrupted; | 1568 interrupted = m_editor_status == EditorStatus::Interrupted; |
1556 if (!interrupted) { | 1569 if (!interrupted) { |
1557 // Save the completed entry in history before returning | 1570 // Save the completed entry in history before returning. Don't save empty |
1558 m_history_sp->Enter(CombineLines(m_input_lines).c_str()); | 1571 // input as that just clutters the command history. |
1572 if (!m_input_lines.empty()) | |
1573 m_history_sp->Enter(CombineLines(m_input_lines).c_str()); | |
1559 | 1574 |
1560 lines = GetInputAsStringList(); | 1575 lines = GetInputAsStringList(); |
1561 } | 1576 } |
1562 return m_editor_status != EditorStatus::EndOfInput; | 1577 return m_editor_status != EditorStatus::EndOfInput; |
1563 } | 1578 } |
1564 | 1579 |
1565 void Editline::PrintAsync(Stream *stream, const char *s, size_t len) { | 1580 void Editline::PrintAsync(Stream *stream, const char *s, size_t len) { |
1566 std::lock_guard<std::mutex> guard(m_output_mutex); | 1581 std::lock_guard<std::recursive_mutex> guard(m_output_mutex); |
1567 if (m_editor_status == EditorStatus::Editing) { | 1582 if (m_editor_status == EditorStatus::Editing) { |
1568 MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockStart); | 1583 MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockStart); |
1569 fprintf(m_output_file, ANSI_CLEAR_BELOW); | 1584 fprintf(m_output_file, ANSI_CLEAR_BELOW); |
1570 } | 1585 } |
1571 stream->Write(s, len); | 1586 stream->Write(s, len); |
1592 std::mbstate_t state = std::mbstate_t(); | 1607 std::mbstate_t state = std::mbstate_t(); |
1593 input.push_back(ch); | 1608 input.push_back(ch); |
1594 switch (cvt.in(state, input.begin(), input.end(), from_next, &out, &out + 1, | 1609 switch (cvt.in(state, input.begin(), input.end(), from_next, &out, &out + 1, |
1595 to_next)) { | 1610 to_next)) { |
1596 case std::codecvt_base::ok: | 1611 case std::codecvt_base::ok: |
1597 return out != (int)WEOF; | 1612 return out != (EditLineGetCharType)WEOF; |
1598 | 1613 |
1599 case std::codecvt_base::error: | 1614 case std::codecvt_base::error: |
1600 case std::codecvt_base::noconv: | 1615 case std::codecvt_base::noconv: |
1601 return false; | 1616 return false; |
1602 | 1617 |